Silent Cacophony's Forum Posts

  • Also, the wiki has a couple of examples of using the two different operators (+ and &), under 'Building strings with &' on this page:

    http://sourceforge.net/apps/mediawiki/construct/index.php?title=Expressions

    There are a few handy bits of info on that page.

  • This is brilliant. It will be a great reference if I ever get around to making a metroidvania game, which I would love to do.

    Thanks for contributing it, UberLou.

  • Sure. Since I decided to learn Python a few months ago, I've found my favorite programming language, ever. I hadn't done any programming for 10-15 years before that, and missed it. I used to use C, Pascal, ARexx, BASIC, and Assembly way back then. I was probably most productive with ARexx, which is somewhat similar to Python.

    Anyway, Python is what finally made object-oriented programming 'click' for me. Even though some feel that it's not fully adherent to the OOP concepts, I think it's quite fine. And it's fine for functional and procedural programming as well.

    So far, I've done a few utility scripts for my own use. Things like batch processing of files and other such occasional tasks. I've also made a couple of quick scripts for work, to process CNC programs from a networked computer to several CNC machining centers, since the existing antiquated software sucks. I plan to make a nice GUI program for that soon.

    I've started work on a Roguelike game, which I plan to implement in Construct, and probably a text-based, pure python version eventually. These types of games are a great argument for using Python. They lend themselves well to OOP methodology, and Python can handle all of the data crunching and most of the logic, while Construct can do the nifty display and behaviors. While I have gotten used to event-based programming in Construct, I am way more comfortable with code when it comes to lots of data and/or logic.

    I have already thought of quite a few more things that I will eventually make in Python. A checkbook accounting program that I will actually USE, Some more utilities for my own quirky computer use, and possibly using it to glue a couple of applications together, to name a few. Hopefully I can still make progress on and finish some games with Construct, too. Seems like there is never enough time.

  • Sounds like it will be quite complex, indeed. While I wouldn't say that Construct wouldn't be able to handle the data storage and manipulation with it's native data structures, I would suggest thinking about using lucid's 's' plugin, or Python Classes, to deal with all of the data needed for such a game.

    I have not tried the 's' plugin. It sounds like it would fit the ticket nicely, though. Since I am quite comfortable with Python, though, I would definitely use classes for each of the components involved. Object-oriented strategy would work well for something like this. At least, one can use Python Classes as a sort of c-like 'struct' in which one can have structured groups of different types of data with meaningful names. These are also capable of pointing to each other, thus 'linking' to each other. It can be a bit tricky interfacing Python code with Construct's events, but it's not too bad...

    I'm not sure of your sectioning of the game universe, but off of the top of my head, I can see I'd want some basic data structures like so:

    Ship:

    • 'Health'
    • Speed
    • Armor
    • Class of ship
    • Armaments (list)
    • fuel capacity
    • current fuel
    • cargo capacity
    • current cargo (list)
    • current location

    Station/Planet:

    • sector located in (link to sector)
    • Type of economy
    • population
    • crime level
    • needed goods (list)
    • surplus goods (list)

    ... etc

    Sector:

    • bordering sectors (list of links to other sectors)
    • ships in sector (list of links to ships)

    ... etc

    ... and much more data than that, depending upon the complexity desired. The trick is to make it as simple as possible in the hidden inner workings of the game, while making it seem complex/realistic to the player. It could be as simple as having an array/list of ships that you loop through every tick of the game, having them make decisions based upon semi-random choices.

  • Hi. This is a common type of scenario that you may run into when developing a game. That is, dealing with discrete states for some aspect of the game. In this case, you'd need to set some sort of 'button pressed once' state when the button has been pressed once, and clear that state if the button is pressed again (as well as taking the desired action), or if the other button is pressed instead.

    As has been mentioned, variables are generally used for such a thing. If this is not going to be needed in other layouts, then a global variable would not be needed. In such a case, a private variable could be added to both sprite objects to keep track of the current state of each. However, in your example, the Shake behavior can be used as a simpler solution by using the Is Shaking condition that comes with it. I made a simple example of how I would implement it, here (v0.99.84):

    http://dl.dropbox.com/u/5868916/Choices.cap

    Here's a slightly abbreviated text version of the main events:

    + MouseKeyboard: On key 1 pressed
    	+ Sprite1: Is shaking
    		-> Text: Set text to " Sprite1"
    		-> Sprite1: Stop shaking
    	+ System: Else
    		-> Sprite1: Start shaking for -1 ms, with intensity 2
    		-> Sprite2: Stop shaking
    + MouseKeyboard: On key 2 pressed
    	+ Sprite2: Is shaking
    		-> Text: Set text to " Sprite2"
    		-> Sprite2: Stop shaking
    	+ System: Else
    		-> Sprite2: Start shaking for -1 ms, with intensity 2
    		-> Sprite1: Stop shaking[/code:zu6vif0g]
    
    Note a few things about how I set up the events:
    [ul]
    	[li]I used [i]On key pressed[/i] instead of [i]On key down[/i]. If I had used [i]On key down[/i], I would have had to add [i]System: Trigger once while true[/i] to that condition to keep it from toggling for every tick that the key is down. [i]On key pressed[/i] will only be true for the duration of the tick that is is detected in.[/li]
    	[li]The state checks are added as sub-events of the triggering action (the key press in this case.) Logically, this is less error prone than trying to make conditions without sub-vents, which can often lead to the undesired result of both states being true in succession, in the same tick, instead of just one.[/li]
    	[li]I used the [i]System: Else[/i] condition instead of an inverted condition: [i](NOT) Is Shaking[/i]. Else is good for checking between two states, as only one will ever be executed in one tick. If you use an inverted version of the first check instead, you can run into the problem of both being true, because the first condition toggles the state, and thus the second is now true because of that...[/li]
    [/ul]
    Anyway, if a variable were used for each choice instead of the Shake behavior, then you'd just need to set it to zero initially, then set it to 1 wherever you had 'Start shaking', and zero wherever you had 'Stop shaking'. Then, replace the 'Is shaking' condition with a check for the variable being equal to 1. Same concept, different method.
    
    I hope this helps.  I write this as much for others who may read this, having a similar problem. I see this type of problem often.
  • Hi. The CommonDialog object can do that. It allows file open & save dialogs, as well as directory and color dialogs.

    Here's a .cap (v0.99.84) with a simple demonstration of an open dialog:

    http://dl.dropbox.com/u/5868916/FileDialog.cap

    Note that the filter does not need to be set, and if you want to start in a particular directory, you can set that in the 'Set initial file' action, and optionally include a default file name in that string as well.

  • Hello.

    Game AI is one of the most difficult aspects of game programming. That's one reason why many games do not feature single player modes.

    It's difficult to say what would work for your needs, but 'custom movement' behavior with conditions dictating what the movement will be based upon what the player does would be a common scenario. There are generally no 'cookie-cutter' solutions to game AI.

    Construct also has 'Line of Sight' and 'RTS' behaviors that can be of great help in this area. RTS seems to be a 'shortest path to...' algorithm, and can be one way to implement chasing.

    Here are a couple of my Google searches that seemed to have some promising links:

    game ai programming

    shortest path algorithm

  • It's a tricky area... what do you think should happen? Do you think the current system (capped at once per tick) is OK?

    I can't really think of any good way for Construct to try and handle such a situation, other than how it does now. Since it really depends upon what one is doing at each interval, I don't think that there can be a catch-all solution.

    I would implement a variation of TimeDelta, as a function, which would report the time elapsed since the last call. Like so:

    + Function: On function "TimePeriodDelta"
    	+ System: Is global variable 'previousTime' Different to 0
    		-> System: Set global variable 'currentTime' to Timer
    		-> Function: Set return value to (global('currentTime') - global('previousTime')) / Function.Param(1)
    		-> System: Set global variable 'previousTime' to global('currentTime')
    	+ System: Else
    		-> System: Set global variable 'previousTime' to Timer
    		-> Function: Set return value to 0[/code:ypm3073b]
    
    This uses two globals, though it would also be good enough without 'currentTime', and accessing the Timer twice instead of once. Anyway, the first time it's called, it returns zero and starts counting time, then every call after will return the difference since last call. It takes one parameter, which the difference in milliseconds is divided by. Pass it the value 1 and it will return milliseconds, or pass it the same interval as your 'every ... milliseconds' condition, and the desired result would be one.
    
    For instance, for a '5 damage per 50ms' event, I pass the function 50, using it in expression form as a multiplier for the desired damage. Much like the TimeDelta.
    
    [code:ypm3073b]+ System: Every 50 milliseconds
    -> System: Subtract 5 * Function.TimePeriodDelta(50) from global variable 'Health'[/code:ypm3073b]
    
    I think a built-in such as this could be useful, but it's not difficult to implement anyway.
    
    I made a simple .cap to test this, which simply appends each result into an EditBox. I did get some odd intervals with low fixed frame rates.
    
    v0.99.84: [url]http://dl.dropbox.com/u/5868916/TimePeriodDelta.cap[/url]
  • There are a couple of other things I can add about this.

    As tulamide mentioned, Construct warns about the resolution of the every x milliseconds condition. However, it's generally not even good to 10ms resolution under the default settings. Under the application settings, "Framerate Mode" is set by default to "V-Synced", which effectively limits the resolution to 1/60 (or 16.667 ms) on my computer. It lags on mine until I set the increment to 17 or more.

    It's actually close to keeping up with the 1ms increment if I change the framerate mode to "Unlimited", where I get a framerate of around 2800. In practice, I've never felt the need to go below 50ms for any such condition, myself.

    Also, I've found it to be a good practice to not rely on exact equality checks for counters such as what you use here. You would notice that it breaks if 1000 is not a multiple of the increment value (as with 17.) I would usually use:

    + System: Is global variable 'MillisecondsB' Greater or equal 1000

    .

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Depending upon what format your source text is in, Python can also make short work of such a problem. If you can import the text into a python string (or list of strings), or even paste it into a Construct EditBox object, you can do something like this:

    text = "one plus one equals two, and four minus three equals one."
    terms = [['three', 'five'],
             ['four', 'seven'],
             ['two', 'four'],
             ['one', 'two']]
    for find, repl in terms:
        text = text.replace(find, repl)
    print text[/code:2l3t03l5]
    
    ...which results in this:
    
    [code:2l3t03l5]two plus two equals four, and seven minus five equals two.[/code:2l3t03l5]
    
    There are some [url=http://docs.python.org/library/stdtypes.html#string-methods]pretty powerful string methods built-in to Python[/url]. You can even do this in Construct.
  • I quite like fan games, myself. I intend to resurrect a few 80's games myself, eventually.

    Graphics are the bane of many a programmer, you know. That's why there are so many roguelikes around.

  • Glad to hear you've worked things out, MrMiller. I hope my example was of some help, even so. I also hope that you weren't put off by my assumption that you were a complete beginner, as I didn't have much information to go on, and I'll usually respond as such if I think it's warranted. Make no mistake, it takes more time and effort on my part to go into more detail in explanations and commenting code, and pointing out resources. I trust that you know that I was simply trying to be helpful.

    I'd still recommend poking around with Python, just because I like it so much, and I think others might as well.

    I'm not by any means an expert either, but if you need any further help, feel free to ask (though I'd probably start a different thread...) Forums are a good place to pool information together from many sources, after all.

  • Hello. I'm assuming that you basically have no experience in programming, from your comments above. If that's the case, you may have figured that you're a bit of a hard case to help. Given that you have figured out ways to make things work, such as using an object that frankly scares me (timeline), then don't give up.

    While Scirra has attempted to make make it less daunting, knowledge of programming is still needed, because setting up event sheets is, indeed, programming.

    Global variables are a very important aspect of programming in any language. In most cases, they represent values (of any given type of data) that can be accessed from within any scope of the program, and that may be changed at any time. In Construct's case, this means that they are shared among all layouts. Given global variables, and some simple conditional events based upon them, one can implement all sorts of things.

    As tulamide mentioned, they are a natural way to implement a timer.

    I've made a commented .cap with an example of a timer implemented in such a way. It sets up two similar layouts, each with a "Text" object to display the timer, where one starts manually and the other automatically. Note that the global variables are of numerical value and the "Text" object handles string values. Construct generally handles converting numbers into strings for use with objects such as the "Text" object quite transparently, as is noted in the .cap.

    I hope it helps (v0.99.84): http://dl.dropbox.com/u/5868916/Timer1.cap

    Also, I'd recommend checking out some beginner programming tutorials in general. I'm partial to Python, as it's widely regarded as easy for beginners, and can be used in Construct as well as on it's own. The concepts in normal computer programming and in event-based programming are very similar, naturally. If you're interested, here are some good resources:

    General beginner's guide: http://wiki.python.org/moin/BeginnersGuide

    A nice tutorial aimed at beginners: http://www.sthurlow.com/python/

    Another found from the first link that I liked: http://openbookproject.net/thinkcs/python/english2e/

    I should add that the two last links both start off with examples done from within the python interactive shell (IDLE), which is great for learning the basics. It simply executes individual commands or command blocks, letting you learn things step-by-step.

    I've also written a simpler version of that shell within Construct, using it's native Python support, so you wouldn't even need to install Python to try the interactive examples given in those. It's here if you're so inclined: http://www.scirra.com/forum/viewtopic.php?f=16&t=6158

  • Hi. It is a known bug with reading global variables containing text from python. It's very unpredictable. Sometimes it works, sometimes it doesn't, sometimes it crashes.

    Anyway, I couldn't figure out much of what you were doing or why you had python commands where you did in that stripped down .cap, but I would deal with the global variables normally through construct events whenever possible.

    As for the specific problem in the .cap:

    + layout2control: On Left Clicked on Box
    -> System: Run Script ("func(System.globalvar('Name'), System.globalvar('Score'))")[/code:31g2cxr9]
    
    ... changed to:
    
    [code:31g2cxr9]+ layout2control: On Left Clicked on Box
    -> System: Run Script ("func('" & global('Name') & "', " & global('Score') & ")")[/code:31g2cxr9]
    
    ... fixes the problem on my computer. This just reads the global vars from the construct event and inserts their values into the string which is to be run as a python script. Note that string values must be enclosed in quotes as I did there, and that the string can't contain the type of quote mark used( ' in this case.)
    
    Otherwise, one can usually write a python function that calls a Construct function, which returns the desired result back to the python function, which in turn returns the result... Eh, sounds worse than it is, really.  I'm not sure that would work well in this case, though. Construct has it's own quirky use of ' quotes with global variables that would probably prove difficult.
    
    Also, I noticed that you were assigning strings to global variables which were defined as numbers. I'm not sure if Construct considers the global variables to be dynamically typed, but seems as though it does.
  • Ah, so if you replace the expression in your clock display event with the one below, it should work fine.

    global('Hour') & ":" & Right("00" & str(global('Minute')), 2) & " " & global('AMPM')[/code:3p2f39y4]
    
    Anyway, Dropbox seems to work quite fine for me. Just in case you didn't know, make sure you put the file in your 'Public' folder within the Dropbox folder, and after it syncs, use the right-click context menu for [i]Dropbox -> Copy public link[/i], which copies it to the clipboard for pasting wherever.