Jump to content

Leaderboard


Popular Content

Showing content with the highest reputation on 05/27/23 in all areas

  1. Lachlan Gemmell

    Problems with Delphi class structure / visibility

    I watched the rest of the video. A few comments. Firstly if you find yourself typing unit names (e.g. LemNeoTheme) outside of a uses clause, 9 times out of 10 you're doing it wrong. Secondly if you find yourself accessing a property through a class name (e.g. TNeoTheme), 8 times out of 10 you're doing it wrong. Think of a unit and the classes inside it as the paper instructions on how to build a table (a real physical table you sit at). The class procedures and functions are the steps you will need to follow to build that table and the data variables inside that class are just a list of the tools you'll need. Lets call this class TFantasticWoodenTableBuilder and it has public property HammerColour (which is a string). Don't think of that TFantasticWoodenTableBuilder class (or the unit that contains it) as being "alive" in any sense. It is as inanimate as an actual set of paper table building instructions. It can't actually physically do or verbally tell you anything. Next a real person Frank comes along and reads those instructions. Frank commits them to memory, goes away and starts building a table. Frank is now an instance of TFantasticWoodenTableBuilder and his HammerColour happens to be red. John reads the instructions and decides to build a wooden table with them. His hammer is blue. We now have two instances of TFantasticWoodenTableBuilder, Frank and John each with their own separate properties (though both called HammerColour) that stores their own respective hammer colours. If you want to know the colour of somebody's hammer you have to ask them (via an instance variable). There's no point asking the class (TFantasticWoodenTableBuilder), it's just a piece of paper, it's not going to talk back to you. The Frank and John instance variables are declared like this var Frank : TFantasticWoodenTableBuilder; John : TFantaticWoodenTableBuilder; This is how they are created (as in memory allocated to them) John := TFantasticWoodenTableBuilder.Create; Frank := TFantasticWoodenTableBuilder.Create; This is how you get or set their hammer colours if John.HammerColour <> 'blue' then ShowMessage('John has pinched somebody elses hammer'); Frank.HammerColour := 'green'; When you're done with them you free these instances so they release their memory Frank.Free; Frank := nil; { to everyone else, lets not make this line a thing please :-) } John.Free; John := nil; So the above code declared two instances John and Frank, created those instances, interrogated their respective hammer colours, and lastly freed the memory associated with those instance variables. Very important, if you're in another unit and you want to know what Frank's hammer colour is, you need to be able to reference the Frank instance through the Frank variable. Now that Frank variable is probably not declared in the same unit as the TFantasticWoodenTableClass. It's probably declared in some other unit. You have to add that other unit to your uses clause, not the unit that has the TFantasticWoodenTableClass in it. How do you know which other unit? Well you have to go searching for it just like you did at 7:04 in your video. How do you know what to search for? Detective work. Welcome to programming. At the 7:30 mark of the video you're getting close to understanding the problem but the actual solution is going to evade you until you learn more about object oriented programming. I haven't watched it but this video might be a good start.
  2. Lachlan Gemmell

    Problems with Delphi class structure / visibility

    I watched the first third of your video. You don't have an instance of your class TNeoTheme to actually retrieve the property from. A theme sounds like something you only need a single instance of in your whole application (I could be wrong on that, but for now let's say I'm right). Since there's only going to be one of them a global TNeoTheme instance variable will be acceptable for now. Let's declare it in the LemNeoTheme.pas unit unit LemNeoTheme; interface type TNeoTheme = class private FLemNames : string; public property LemNames : string read FLemNames write FLemNames; end; var MyTheme : TNeoTheme; { this variable MyTheme will represent the single instance of the class TLemNeoTheme } { it does not however create that instance here, just declares the variable } implementation { code, code, code, more code } { now at the very bottom of the unit, just before the final end. statement } initialization MyTheme := TNeoTheme.Create; { this is where the memory for the instance of TLemNeoTheme is allocated } { and assigned to the MyTheme variable. It will occur when the program starts } finalization MyTheme.Free; { this is where the memory for the instance is released. It will occur when the program shuts down } MyTheme := nil; end. Now over in TGamePreviewScreen.GetTextLineInfoArray you access the LemNames property via the MyTheme instance variable Result[2].Line := Result[2].Line + IntToStr(zombies + lemmings) + MyTheme.LemNames; Please be aware that we're only scratching the surface with the code above. It's probably appropriate for your TNeoTheme class but most other class instances will not be global variables like this and will require other techniques. Actually surely there is already a TNeoTheme instance somewhere in this code already. Do a Find in Files search for "TNeoTheme.Create". Ignore the actual constructor implementation but you'll likely find something like: AnotherThemeInstanceVariable := TNeoTheme.Create; That variable AnotherThemeInstanceVariable is probably the one you should be using rather than the MyTheme variable I declared and created above. I hope you'll take this in the spirit that it's intended in but a quick look at the project on that video makes me think you've picked a pretty big mountain to climb for your first outing. Maybe go find a few gentle hills to train on first before attempting something as large and complex in scale as game development.
  3. I have worked on a port of my Bitmaps2Video-encoder to using Windows Media Foundation instead of ffmpeg, since I wanted to get rid of having to use all those dll's. Now, before posting it on GitHub, I'd like to run it by the community because of my limited testing possibilies. I also hope that there are people out there having more experience with MF and could give some suggestions on the problems remaining (see below). Learning how to use media foundation certainly almost drove me nuts several times, because of the poor quality of the documentation and the lack of examples. What is does: Encodes a series of bitmaps to video with the user interface only requiring basic knowledge about videos. Can do 2 kinds of transitions between bitmaps as an example of how to add more. Supports file formats .mp4 with encoders H264 or H265, or .wmv with encoder WMV3. Does hardware encoding, if your GPU supports it, falls back to software encoding otherwise. Uses parallel routines wherever that makes sense. Experimental routine to mux in mp3-audio. Only works for H264 and WMV3 right now. Requirements: VCL-based. Needs the excellent MF headers available at https://github.com/FactoryXCode/MfPack. Add the src-folder of MFPack to the library path, no need to install a package. Needs to run on Windows10 or higher to make use of all features. Not sure about Delphi-version required, guess XE3 and up is required for sure. Problems remaining: I'm not too thrilled about the encoding quality. Might be a problem with my nVidia-card. The audio-muxer should work for H265, because it works when I use ffmpeg. But with my present routine the result just plays the audio and shows no video. I haven't yet figured out how to insert video clips. Major problem I see is adjusting the frame rate. Renate Bitmaps2VideoWMF.zip
  4. Uwe Raabe

    Community license

    It is my understanding that Free = $0, so basically you simply sell it for $0 until your revenue reaches $5,000. Note that this includes any donations, even if the app is free. Also any paid support or training you are giving around your apps is probably counted for that limit. As the FAQ is not a legal document I add the respective chapter from the license here: Anyway, if you want to make sure, you should better ask Embarcadero directly.
  5. Minox

    Just open folder ( Android )

    If your intention is to open the explorer automatically in a specific location, I don't think it's possible to do it with the system one. Third-party ones do it instead, but I've never faced the problem. This session could be a good start to understand if there is a possibility to do it.
  6. Minox

    Just open folder ( Android )

    I use this: uses Androidapi.JNI.GraphicsContentViewText, Androidapi.Helpers, System.Messaging, Androidapi.JNI.Net, Androidapi.JNI.App, PROCEDURE TForm1.GetFileBrowser; VAR Intent : JIntent; ReqCode : Integer; BEGIN ReqCode := 1000; Intent := TJIntent.Create; Intent.setType(StringToJString('*/*')); Intent.setAction(TJIntent.JavaClass.ACTION_GET_CONTENT); Intent.putExtra(TJIntent.JavaClass.EXTRA_ALLOW_MULTIPLE,true); TMessageManager.DefaultManager.SubscribeToMessage(TMessageResultNotification, procedure(const Sender : TObject; const aMessage : TMessage) VAR msgRES : TMessageResultNotification; begin msgRES:= TMessageResultNotification(aMessage); If msgRES.RequestCode=ReqCode Then if (msgRES.ResultCode=TJActivity.JavaClass.RESULT_OK) Then Begin URIfileTrn := msgRES.Value.getData(); //URI sing file selez If URIfileTrn=Nil Then //multiselez ClipDataF := msgRES.Value.getClipData; End; end); TAndroidHelper.Activity.startActivityForResult(Intent, ReqCode); END; and then via thread process the URI
  7. Brandon Staggs

    Problems with Delphi class structure / visibility

    The problem with that is pseudo-code is an extreme abstraction. It's not helpful when trying to determine the cause of compiler errors. Your pseudo-code conflated units with classes -- I think perhaps an OOP primer would be useful for you. You might start by getting Cantu's Object Pascal Handbook or some other free basic introduction to coding with Delphi. https://lp.embarcadero.com/Object-Pascal-Handbook-2021
  8. Tom Chamberlain

    Problems with Delphi class structure / visibility

    The one thing no one has pointed out: Unit1 TClass1 PropertyA Unit2 Uses Unit1 {the unit name, not the class inside the unit name} Another useful link is https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Programs_and_Units_(Delphi)
  9. Dalija Prasnikar

    Problems with Delphi class structure / visibility

    Without seeing where LemGame is declared and how it is impossible to say why you have an error. It is also important to note that sometimes you may get error in the IDE (read squiggly lines) in some perfectly valid code. You should always try to compile code to see real errors. also, when you do get compiler error, you should fix them in order they appear as the first error can cause subsequent issues for the compiler and it is possible that compiler will show more errors in otherwise valid code. But, it seems like your main problem is not with Delphi but with OOP principles in general as you are trying to access properties in a class without creating instance of a class. Class is just a template from which object instances are created. Before you create object instance data (class fields and properties) don't exist in memory, so there is nothing you can access there. The exception to that are class fields, properties and methods that are additionally marked with class descriptor. Those can be accessed directly. They are basically global variables that are organized under class namespace. See https://docwiki.embarcadero.com/RADStudio/Sydney/en/Properties_(Delphi)#Class_Properties Purpose behind creating object instances from class before using them is that most of the time you will need more than one. For instance, you can have one global object instance of a game, but you will need more instances of game characters or other game objects. Think of it, class gives you description about attributes and functionality of a person, and when you construct object instances of that class you will get separate persons: Joe, Mike, Alice... I would advise you to read a bit about Delphi language and some basic concepts. good place to start is https://learndelphi.org/ and Delphi Language Guide https://docwiki.embarcadero.com/RADStudio/Sydney/en/Delphi_Language_Reference
  10. Joseph MItzen

    Problems with Delphi class structure / visibility

    Python is more object-oriented than Delphi (EVERYTHING is an object - types, functions, classes, even numbers) and there is no enforced "private" setting. Privacy is only by naming convention as a guideline. And you don't even need to save its code to a cassette tape! 🙂 There's basically two schools of thought in programming language design - that you have to hide and control everything to "protect" users or developers or the system, and the other school is about giving power to the developers to do whatever they wish and put responsibility for doing it properly and safely on the developer, not the language/compiler. I believe Guido Van Rossum, the creator of Python, dubbed the latter design view the "we're all adults here" philosophy. Which view has more merit is up to designers and developers to decide for themselves, but it's clearly possible to design object-oriented features into languages using either approach. And on a marginally-related note, the Internet Archive had a great write-up recently about programs stored on cassette tape... 🙂 https://blog.archive.org/2023/05/02/the-easy-roll-and-slow-burn-of-cassette-based-software/
×