PDA

View Full Version : game help


spriggan
06-09-2003, 04:41 PM
I'm almost finished with a breakout style of game, the last thing I need to do is fix a problem with the ball missing a brick. I realise that this is a problem with frame dependent hittest. Does anyone have any Idea how to go about doing a frame indepent hit test in this case? I'm checking the location of the ball via grid, and if the ball is in a grid cell that has a brick then a hit test occures.

retrotron
06-09-2003, 05:04 PM
A number of options there. You can use updateAfterEvent(), setInterval(), or just increase the frame rate.

spriggan
06-09-2003, 05:13 PM
I don't think changeing the frame rate would do anything. The problem is that the speed of the ball. So when flash redraws it the ball is past the brick.

I'm not fimilar with updateAfterEvent() or setInterval(). Could you explaine them to me?

retrotron
06-09-2003, 05:18 PM
For setInterval(), see senocular's article:
http://www.umbc.edu/interactive/flash/tutorials/showpage.php?p=setInterval

For updateAfterEvent(), see the entry in the ActionScript dictionary:
http://www.macromedia.com/support/flash/action_scripts/actionscript_dictionary/actionscript_dictionary815.html

and this:
http://www.macromedia.com/devnet/mx/flash/articles/actionscript.html

Let me know if you have questions.

spriggan
06-09-2003, 05:49 PM
neither of those will do what I need to do. What I need done is a way for flash to tell if during moveing from one frame to another a collision happened or not.

spriggan
06-09-2003, 07:58 PM
Maybe if I post the game it would make sence.

http://www.timewastersguide.com/VG/NickelCade/index.php

retrotron
06-09-2003, 09:16 PM
Thanks, seeing it does help. So you don't have any tiles working at the moment? Is that right? Why not just test for collision the same you did it with the ball and the paddle?

spriggan
06-09-2003, 09:28 PM
No the tiles do work fine. What's happeneing is that in one frame the ball is at the bottem of the brick, but not hitting it. In the next frame flash redraws (that's how animation works in flash) the ball but the speed of the ball puts it on the other side of the brick. No collision took place. If I did it the same way the as with the paddle (a normal hittest) it would do the same thing. The way I'm doing it now uses less memory. I think flash can roughly handle 100 calculations in a frame, this would have 400+.

retrotron
06-09-2003, 09:38 PM
So why doesn't the same problem happen with your paddle?

spriggan
06-10-2003, 12:00 AM
It does just very rarely. I guess it just has to do with where the paddle is located and it's thickness.

agent81
06-10-2003, 12:06 AM
Hey sprggan, basically it comes down to the problem that using hitTest is a really bad way to write breakout (or any tile based game).

i tried to explain this in another thread, but got myself into all sorts of trouble, and only managed to confue everyone.

so you've got a few options, if you've got time to re-write a bit of your engine, goto

http://www.actionscript.org/forums/showthread.php3?s=&threadid=28223

and see if you can make sense of the difference, if you can, then I'd be glad to help.

If you don't have too much time, or are happy to put up with the way you are doing it now, you've got two choices

1. make the ball slower
2. make the blocks bigger

easy:D

retrotron
06-10-2003, 12:15 AM
Here's how I see it, take it for what it's worth:

Flash is an event driven language, so the only time you can "check" for a hit test is during an "event". So if the ball hits the tile in between events (say, in between when a hittest runs in one frame and when it runs in the next frame), then there's no way for Flash to know something had collided (i.e. note the past tense, you can't test things that happened, you can only test things that happen at the time of the event).

The burden lies on the programmer to create such events so we can actually run code during these events (in your case a hittest). If the frame rate is too slow, we have to increase the frame rate so that onEnterFrame() will execute more frequently. Of course, that's no good for you because then the ball will be cruising superfast. Or, we have to use setInterval or some other kind of iteration to cause an event to happen more frequently. I.e., if you had a function called "testHit" that tested whether the ball was over a tile or not, you could use setInterval to execute that function every x milliseconds:

// check whether ball is over a tile
function hitTest() {
// hittest code here
} // end hitTest()

// execute testHit() every 50 milliseconds, regardless of framerate
myInterval = setInterval(testHit, 50);

Etc. etc...anyways, hope something here makes sense or gives you some ideas

retrotron
06-10-2003, 12:16 AM
Ah, agent81 put a post there, cool. His solution is definitely easier. :)

spriggan
06-10-2003, 12:28 AM
Ya Agent81 I tried to help on that thread too, I'm doing things basicaly the same as you:

function moveBall() {
ob = game.ball;
var tempx = ob.clip._x+game.speedx;
var tempy = ob.clip._y+game.speedy;
var cellx = Math.ceil(tempx/game.spacingx);
var celly = Math.ceil(tempy/game.spacingy);
var tempCell = game["cell"+cellx+"_"+celly];
if (tempy>=500) {
game.speedy=-10
ob.diry="up";
game.score=game.score-20;
}
if (tempy<=10) {
game.speedy=10
ob.diry="down";
}
if (tempx<=10) {
game.speedx=+10
ob.dirx="right";
}
if (tempx>=350){
game.speedx=-10
ob.dirx="left";
}
if ((tempCell.type >1)&&(tempCell.clip.tile._visible!=false)){
if (game.ball.diry=="up"){
game.speedy=10
}
if (game.ball.diry=="down"){
game.speedy=-10
}
if (game.ball.dirx=="right"){
game.speedx=10
}
if (game.ball.dirx=="left"){
game.speedx=-10
}
if (tempCell.type!=5){
tempCell.clip.tile._visible=false;
game.bricks=game.bricks-1;
game.score=game.score+100;
//trace (game.bricks);
}
}
ob.clip._x = ob.clip._x+game.speedx;
ob.clip._y = ob.clip._y+game.speedy;
}



type 1 is an empty tile and 5 is an unbreakable one.
The set interval would work but I'd have to change my whole hitest.

agent81
06-10-2003, 01:23 AM
yeah right, you are doing it the right way. personally i would just make sure that the speed of the ball never got bigger than the height of the tile, but then i am also a bit lazy at times....

what you need to do is to use a line intersect function, rather that a point intersection. I actually did something like this, when i last wrote breakout, it works well, because you can also work out where the ball bounced, (e.g on the side or bottom of the cube) and change your balls movemants accordingly.

I'm a bit out of time today, but I'll post what i did below. It'll be completely useless to copy and paste it, but you should be able to work the formula out from it....?:D

this.tileCheck = function() {
var cell_x = Math.ceil((this.x-this.sLeft2)/this.across)-1;
var cell_y = Math.ceil((this.y-this.sTop2)/this.down)-1;
if (this._parent.blockStore[cell_x][cell_y].blockOn) {
this._parent.blockStore[cell_x][cell_y].blockStrength -= this._parent.ballPower;
if (this._parent.blockStore[cell_x][cell_y].blockStrength>=0) {
var path = this._parent.blockStore[cell_x][cell_y].path;
var ylength = (this.y-this._y);
var ymov = this.yspeed/Math.abs(this.yspeed);
var tileY = path._y+(ymov*path._height);
var pcnt = ylength/(tileY-this._y);
var ballX_pcnt = (this._x-this.x)*pcnt;
if (ballX_pcnt<0) {
if (this._x+ballX_pcnt<path._x-(path._width/2)) {
this.switchX();
this.x += this.xspeed;
} else {
this.switchY();
this.y += this.yspeed;
}
} else {
if (this._x+ballX_pcnt>path._x+(path._width/2)) {
this.switchX();
this.x += this.xspeed;
} else {
this.switchY();
this.y += this.yspeed;
}
}
if (this._parent.blockStore[cell_x][cell_y].blockStrength == 0) {
this._parent.blockStore[cell_x][cell_y].blockOn = false;
this.tillNewBall++;
if (this.tillNewBall>this.makeNewBall) {
this.tillNewBall = 0;
this.makeNewBall *= 2;
this._parent.addBall(this.x, this.y);
}
if (Math.random()<.3) {
this._parent.makeBonus(path);
}
path.removeMovieClip();
_root.looseBlock();
}
} else {
if (Math.random()<.1) {
this._parent.makeBonus(this._parent.blockStore[cell_x][cell_y].path);
}
this._parent.blockStore[cell_x][cell_y].blockOn = false;
this._parent.blockStore[cell_x][cell_y].path.removeMovieClip();
_root.looseBlock();
}
}
}


sorry, thats got a whole lot of code, to control bonuses, block strentghs etc, but the first bit, works out where it hits the block. this won't actually solve your problem, but you should be able to add something from your percent values that'll tell you what you need to know.....

spriggan
06-10-2003, 02:51 AM
Sweet thanks, that code realy helps. I shouldn't have much of a problem modifying it.

agent81
06-10-2003, 03:48 AM
no problems, let me know how you go, and if you improve on what I've done, post it up, I'd love to see...:D

spriggan
06-10-2003, 03:59 PM
Hey Agent81 could you explaine this to me

var path = this._parent.blockStore[cell_x][cell_y].path;


It the .path at the end something in an object?

Necrin
06-10-2003, 06:13 PM
Hi i'm trying to make a little platform game. I have got the keyboard input sorted and I'm animating the main character by frame labels.

I'm having trouble getting the character to face the driection it's moving. So I want the character to flip horizontal when I press left or right. I think it has something to do with using xscale or yscale but I dont know how to get it working. Cheers :)

spriggan
06-10-2003, 06:19 PM
set the faceing or direction to 100

then when you use the left key
Mymovieclip._xscale = -faceing;

right key:
Mymovieclip._xscale = faceing;

agent81
06-10-2003, 11:34 PM
Hey spriggan, yeah you are right. when i create the original array, i make each entry an object, with all of the details of the block in that array, path is a direct reference to the movieclip, so i can say

this._parent.blockStore[cell_x][cell_y].path.removeMovieClip
//or
this._parent.blockStore[cell_x][cell_y].path.gotoAndStop(2)
//etc


the var path bit, just saves that link, so i can reference it more than once in that function, without having to write the full path...

i also store things like the blocks strength, in that same object.

hows it going, is it making sense??

spriggan
06-10-2003, 11:51 PM
Thanks, I wasn't sure if path was some varable or not. I've started to use objects too. It's going good, I'm adding the code that detects the part of the tile the ball hits now. Very useful.

Necrin
06-11-2003, 09:41 PM
Thanks I got that working now. I am now trying to get the jump ability working. I have scripted it so when you press space it plays the jump frame label. but if you hold down space it pauses the jump in mid air. Is their anyway of incorporating a system of gravity to make the character fall even if you hold down the button.

spriggan
06-11-2003, 11:37 PM
Ya you can, but if you want to do it the easy way add a varable that's something like isJumping=false then when you hit jump make it false.


MyJumpFunctoin=function(){
isJumping=true;
//jump code, once the jump is complete set isJumping=false

}

onClipEvent (keyDown) {
if (Key.isDown(key.SPACE)) {
if (!isJumping) {
myJumpFunctoin()

}
}

Something like that should help.