Ace_Blue
1087 posts
|
Topic: Game Design /
Twitch: The Game Of Frustration ALPHA
My first reaction: “ARGH it’s a Unity game close the tab close-the-tab close-close-close-DAMMIT-CLOSE before FF crashes! Phew…” After that, the game itself did not generate any strong emotions. There seems to be no point beyond a death wish to take the first teleporter, it’s much simpler to just bypass it. I did not play a single game that lasted more than 15s and yet I feel like I’ve seen all the content the game has to offer. And the collision detection is terrible.
I can tell from the title that I’d be wasting my time if I argued for a gentler difficulty curve, just be aware that your game has niche appeal. The general player base has very little patience for a game that tells them they’ve lost four to eight times per minute, and requires restarting from scratch every time with no indication that they’ve ever accomplished anything.
Edit: Normally I sugarcoat my game feedback but I figured that someone whose avowed goal is to bluntly dish out frustration to their players can take a little bluntness themselves.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
Deeper Topic (part 3): Events to the rescue!
I would separate keeping track of what keys are pressed how often for how long from deciding what to do with key presses. This way the key handler can be the same whatever the project, whereas the decision part can be written with your specific project in mind, taking advantage of having a ready-made keyboard handler.
The keyboard handler can be as simple as a Vector of ints, with length around 250 (can’t recall the exact number of keycodes off the top of my head.) When a key is released, take its keycode and store the frame number at that position in the array. When a key is pressed take its keycode and look up that position in the array. If the value there is >=0 store -1 instead, else ignore it. On enter_frame loop over the array, decrementing by 1 every value that is already <0.
And voila, you are now keeping track of how long each key has been pressed if it’s pressed and when it was last pressed if it’s not, using only a single int for each key. Only caveat: a value of -N indicates the key is in its Nth frame of being pressed, not that it has been pressed for N full frames (difference of 1).
Edit: I just noticed your downKeys() function counts key repeats, which is bad (as your comment indicates you are aware), but not because of Adobe. It’s bad because key repeat delay and frequency are system-dependent, and Flash has no control over them (nor should it have any. Do you want random Flash apps making changes to your keyboard settings? I don’t.) You should be counting frames of continuous pressing, or time difference between the initial press and the ultimate release.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
[AS3] Getting function arguments from an array [Solved!]
Originally posted by Elyzius: Regarding casting, something magical seems to happen when you cast variables, especially when storing them in arrays and dictionaries. (Or more likely, the Flex compiler isn’t as smart as we would want it to be, so we have to resort to tricks like that to optimize our code.)
Thanks for the link, that’s absolutely mind-blowing. The only explanation I can see for it is that the extra cast is not extra at all but occurs instead of the implicit cast, and is faster. What’s mind boggling to me is that the speedup occurs even in the case of Vector, where the stored type has to match the variable type or the compiler will not accept it. There shouldn’t be any need for any recasting, implicit or otherwise, in that case!
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
Feedback Wanted: Feed Me Your Thoughts!
In lieu of feedback, here are some questions.
How long do you have for this project? (This will constraint the scope of your project. A lot.)
Can you still graduate if your project fails? (Your answer will determine how ambitious you can afford to be.)
Have you gotten approval for your project from the people in charge at your institution? (They will or will not approve based on a variety of factors that may or may not match your expectations. Make sure whoever’s in charge of your grade is on the level with what you’re trying to do and they deem it a worthwhile project.)
Have you ever coded anything resembling an economic simulation?
Do you know the general principles of how stock markets work? (Mechanistically I mean, how prices are determined, how and why orders get executed, how to handle new orders, how to resolve trades, that kind of stuff.)
What’s the minimal number of components your project can have and still be functional?
How long would it take you to code a no-frills prototype to show your adviser (or whoever is in charge)?
Does your project have to be multiplayer? Have you coded multiplayer games before? (hint: It’s a whole lot tougher than making single-player games!)
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
[AS3] Getting function arguments from an array [Solved!]
Woah, this thread moves a lot faster since I’ve closed it! ;p
Regarding calling functions through a variable and using apply(), I know those are half an order of magnitude slower than regular calls. And my updating routine (which reacts to an enter frame event) is peppered with them. To make matters worse, why yes, I am testing component-based design and my ability to use it by making a bullet hell. And yet I’m not worried.
Maybe I’m insane, or maybe I’m thinking that the bottleneck of any bullet hell game is going to be the number of bullets displayed on the screen every frame. Even if I had 500 bullets on screen at once, which is probably about right in the heat of a boss fight with a nicely upgraded player ship, I don’t think the act of constructing a dozen bullets or so (the only part that requires function variables and apply()) in a given frame (and then again not even every frame) is what’s going to bring the CPU to its knees. Maybe I’m wrong, maybe not, which is why I’m trying it out: to find out.
I’m thankful for the warning but do not worry for me, I have these concerns in mind and I’m being careful.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
[AS3] Getting function arguments from an array [Solved!]
Thank you for the answers. Function.apply() is exactly what I was looking for. I’m marking the topic as solved.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
Error #1063: Argument Error
Thanks for the info, I had no idea (I only use FlashDevelop.) Thanks also for giving me one more reason to love FD.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
How to restart game correctly?
If you have more time (your post made it sound like there’s a deadline of some sort breathing down your neck) take all the initialization stuff and shove it into an initialize() function. Call initialize whenever you start (or restart) the game, which will reset all critical variables to their default values. You’ve named them, so you know what they are.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
[HELP] (SOLVED) How to repeat Sound with Timer AS3
The event triggers every time the sound finishes playing, and calls a function whose first order of business is to play the sound. So as long as you spawn that listener anywhere (that gets executed before the sound plays for the first time) playing the sound once directly results in playing the sound continuously. What you want is to remove both instances of that listener, but keep the one linked to the timer, so that every time the timer rings (every 17s in your case) the sound is played once.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
[HELP] (SOLVED) How to repeat Sound with Timer AS3
Your feeling is partially right. This:
titleWhooshSoundChannel.addEventListener( Event.SOUND_COMPLETE, onTitleWhooshFinished);
makes your sound loop. You already have a timer, why did you also put this, and in two separate functions?
I recommend linking both the visual effect and the sound to the same timer, otherwise if they’re not perfectly in sync you might end up with a shift over time. I don’t know how long you expect players to stare at your logo, but still you would not want to spoil the effect.
Edit: As an aside, in case it’s not clear to you, event listeners remain until they are physically removed, you don’t need to reinstate the listener every time it triggers.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
[solved] Multidimensional array having some single elements not being copied properly
new Array(x) where x is an int builds a new array of length x, every element of which (indexed from 0 to x-1) is undefined. If what you want is an Array containing a single element of value x you should do [x]; instead.
So basically: to repeat the first part of your list:
static public var CONNECT_NODES:Array = [
//level 1
[
[7, 11],
[7],
[8],
[8],
[9], // and so on...
Edit: Went all out and changed every single ‘new Array(’ in that code to ‘[’. Isn’t it much nicer and more compact, too?
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
Health Bar
Originally posted by Goldnrage:
I searched for every possible solution and none of them work.
Surely that can’t be true. Post your code (formatted!), the error you get, explain in as much relevant detail as you can exactly what the problem is and how you’ve tried to solve it. We can’t help you unless you tell us what’s wrong.
If you’d really much rather chat with someone so they can walk you through it step by step, maybe try the game development room (GDR) and see if someone there will help?
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
Error #1063: Argument Error
Please post the entire constructChildren() function. If you can get a line number for where the error is located, take a look there too. Something as simple as a blank initialization (something like private var truck:iceTruck = new iceTruck();) could have caused this error. The line you quoted could not.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
[AS3] Getting function arguments from an array [Solved!]
I’m trying to automate setting up objects, and I need to figure out a way to pass a series of parameters of unknown length into a function. Basically, I have objects that conform to the component-based description Drakim recently posted about: An ‘entity’ with no particular function to which are attached a series of ‘components’.
Each of my components has a different class, but any that needs setting up has a setup() function which takes a number of arguments that is dependent on the class of the component. For instance, a PositionComponent is set up with 3 Numbers so that if ‘pos’ is the position component
pos.setup(10, 20, 30);
is a valid call. On the other hand, an Animation component is set up with more parameters, the first one of which is a BitmapData, and some of which are optional.
I’d like to set up a array (or another data structure) in such a way that I could call its elements to fill in the blank in the setup process. Ideally something like:
parameters = [[ PositionComponent, [10, 20, 30]],
[AnimationComponent, [bmd, 10, 50, true, null, 7]],
[SpeedComponent, [0, 0]]];
for (var i:int = parameters.length - 1; i >= 0; --i)
{
var comp:Class = parameters[i][0];
var arguments:*here's my problem what should this be* = parameters[i][1];
(entity.getComponent(comp) as comp).setup(arguments);
}
So long story short I need to figure out the proper way to package my arguments so they can be reinserted in the function call.
|
|
|
Ace_Blue
1087 posts
|
Topic: Kongregate /
Badge Suggestions!
Originally posted by Precarious:
Assuming it gets API, I feel that N should be badged despite its current rating. The game kind of reflects the culture change that’s gone on over the past half decade and more at Kongregate: the player base that made it “by far the most requested” game in 2007 seems (collectively) less interested in a difficult, relatively unforgiving platformer. But N occupies an important place historically in flash gaming; older badges are not removed as their popularity wanes, in part because the past means something. If N doesn’t speak to what Kongregate is now, it does to what it was. I’m hoping the rating will rise a bit, but the truth is that the game earned its badges years ago.
Some games that came out in 2007 that would have gotten badges at the time (had there been Kong badges in 2007!) would not get them if they were released today. Sadly, with its poor controls, N is one of them. Also, I would argue that there wasn’t so much of a culture change among flash gamers than a sea change in quality among flash developers. A lot of what was considered good in 2007 is barely tutorial material by today’s standards. N’s rating simply reflects that.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
Deeper Topic (part 4): Examples and advanced techniques
A few days later, having thought about the issues I have come up with a solution. But first, have an example.
Here’s how it works: There are three pools of entities, enemies, bullets and effects. Collision detection (except collision with the player which cannot occur in the example) operates at the pool level, enemies can collide with bullets, nothing else can collide (effects in particular are completely inert). Anything that can collide possesses a radius component which is just a repository of three variables: the collision range, and an x/y offset from the position of the object to get the center of its collision radius.
The pool-level collision detection tests every element of pool1 against every element of pool2 to see if any inter-entity distance is shorter than the sum of the entity radii and, if a collision is found, dispatches collision events (HIT) to both entities.
Bullets react to HIT events by expiring (dispatch an EXPIRED event to themselves so their pool handler will remove them from the game) and by spawning a bullet explosion effect.
Enemies react to HIT by spawning a shield effect which tracks their position.
It works relatively well, although bullets turn out in the end to be much more complex objects than one would expect a priori. In addition to their mandatory pool handler component they contain the following: Position, speed, animation, straight move, lifetime, radius and hit detection components.
Some things I’m not happy with:
Effects carry a position match component so shield effects can follow the enemy ship around. bullet explosions do not use this property but must carry the component in order to share a pool with shield effects. I thought part of the point of using component-based design was that entities would not have to carry properties they don’t need.
When two entities collide each receives in the data object that accompanies their HIT event the identity of the entity that hit them. I will need this for damage calculations, for instance. I need it right now to compute the angle the enemy was hit from so I can rotate the shield effect appropriately. Consequently, the shield effects are spawned at an angle which is passed as a parameter. This angle is also calculated and passed to bullets that hit enemies when they spawn their explosion effect even though they neither need nor use it. Again, component-based was supposed to avoid that.
Debugging components is a real headache since the code is so delocalized it gets hard to see where failure occurred. This is particularly true when something is supposed to happen on the screen and nothing shows. I’ve wasted a lot of time like this.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
latent controls issue
No delay on Chrome here either. On a side note I really hope that’s an optional bonus level or something like that because boy are those gaps annoying!
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
One-way platforms
Joking aside, what I ended up doing when I faced this problem was to have a behavior for each tile side (up, down, left and right.) My behaviors ended up being FREE, BLOCK, and KILL. By detecting which side the character was trying to enter from I could apply the appropriate behavior. Solid block would BLOCK on all sides, one-way platform would BLOCK on top but FREE on the sides and down, while spikes would KILL at the pointy side and block on all others. Once the character was inside a tile they were free to leave it from any side, provided the tile they were trying to enter would allow it.
You can check the behavior on my profile (the game’s called GiTD23 if memory serves.)
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
One-way platforms
Yes. Computers can’t see white.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Design /
[Feedback] Control scheme
I’d like to get people’s opinion about how comfortable they feel with a top-down shooter ship yawing as it moves around. Specifically, do you find it difficult/troublesome to aim at the top ship in this toy and how do you feel it compares to aiming/leading when the ship always shoots straight up?
Additionally, do you think the experience would be enhanced if the player could hold their ship still (but still rotating to follow the mouse) by pressing a key or the left mouse button?
|
|
|
Ace_Blue
1087 posts
|
Topic: Kongregate /
Why "N" is not on Kongregate
I think the biggest problem is that it has crappy controls. I know it’s the main reason I downrated it. I remember the original’s controls not being all that great all those years ago, but this is beyond the pale. Six years to get a control scheme that’s almost unusable, someone is not taking their players seriously.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
Show us a screenshot of what you're working on!
Oh Feffers, don’t insult your players. Not only it’s not nice, but it hasn’t been edgy for decades!
|
|
|
Ace_Blue
1087 posts
|
Topic: Kongregate /
Directory of Kongregate Chat Rooms
Don’t remove the labeling on the x-axis, but change it to a time unit rather than a sample number (if that’s what it is now?), because at this point it’s kind of hard to tell if I’m looking at minute-by-minute changes or seasonal variations. And yes, the data points could go without the graph losing anything.
Edit: I just realized I didn’t make it clear but yes, it is an awesomely cool chart.
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
Deeper Topic (part 4): Examples and advanced techniques
I’d have to think about it. I don’t see what components I’d want to attach to the pool off the top of my head, but it’s worth thinking about. I think it also converges toward Drakim’s talk of having components that can contain entities, in that the pooling aspect could be handled by a component, but I had some wine with dinner and the concept is too recursive for my diminished mental faculties right now…
|
|
|
Ace_Blue
1087 posts
|
Topic: Game Programming /
Deeper Topic (part 4): Examples and advanced techniques
It’s funny because they do end up simply walking into Mordor…
Anyway, here’s the entity pool class, comments below.
package
{
public class EntityPool
{
private var inuse:Vector.<Entity>;
private var reserve:Vector.<Entity>;
private var template:Vector.<Class>;
private var size:int;
public function EntityPool(poolSize:int):void
{
size = poolSize;
}
public function setTemplate(componentList:Vector.<Class>):void
{
template = componentList;
inuse = new Vector.<Entity>;
reserve = new Vector.<Entity>;
for (var i:int = 0; i < size; i++) reserve[reserve.length] = generateEntity();
}
private function generateEntity():Entity
{
var entity:Entity = new Entity();
for (var i:int = 0; i < template.length; ++i)
{
entity.attachComponent(new template[i]() as ComponentInterface);
entity.attachComponent(new PoolHandlerComponent() as ComponentInterface);
(entity.getComponent(PoolHandlerComponent)
as PoolHandlerComponent).setup(this);
}
return entity;
}
public function add():Boolean
{
if (reserve.length == 0) return false;
inuse[inuse.length] = reserve[reserve.length - 1];
reserve.length--;
return true;
}
public function removeAt(index:int):Boolean
{
if (index < 0 || index >= inuse.length) return false;
reserve[reserve.length] = inuse[index];
inuse[index] = inuse[inuse.length - 1];
inuse.length--;
return true;
}
public function remove(entity:Entity):Boolean
{
for (var i:int = inuse.length - 1; i >= 0; --i) if (inuse[i] == entity)
{
reserve[reserve.length] = entity;
inuse[i] = inuse[inuse.length - 1];
inuse.length--;
return true;
}
return false;
}
public function get last():Entity
{
if (!inuse.length) return null;
return inuse[inuse.length - 1];
}
public function applyEvent(keyword:String, data:Object):void
{
var takeout:Boolean;
for (var i:int = inuse.length - 1; i >= 0; --i)
inuse[i].dispatchEvent(keyword, data);
}
}
}
Overall it should look pretty straightforward. The idea is to create the pool and give it a template (a list of component classes that all entities in the pool have) at game start. The pool has two vectors of entities: the reserve, which is where all entities start, and where they hang out when they are not holding game information, and the in-use vector where they go when they need to be considered as part of the game. When a component that has access to the pool wants to introduce an entity into the game they add() one (take it from the reserve and put it in the inuse pile), which goes at the end of the inuse vector, then get last() to obtain a handle on it. Then they can initialize all of its components that are part of the template, and from then on they lose track of having ever introduced it. The game can introduce events to the pool through the applyEvent() function, which targets only those entities which are currently in use, thus avoiding wasted CPU cycles. Note that entities in both vectors are unsorted, allowing fast splicing.
Edit: What I would like instead of the pool handler would be the ability for a component to dispatch an event that bubbles up to the entity first, and then to the pool, with a mention of which entity’s component dispatched it, so I could remove entities from the pool at the pool level. Right now I need a component to know what entity it’s on and in which pool that entity is, and to call pool.remove(entity). It’s inelegant.
Edit2: How do you get ‘pre’ formatted code to not screw up the text when it exceeds the width of the page?
|