So I'm trying to make a ball hit the wall and bounce off it just like pong game. but for some reason when ball thinks the canvas is smaller that it actually is.
here is my onDraw code:
canvasWidth = canvas.getWidth();
canvasHeight = canvas.getHeight();
if (flag) {
x = (int) canvasWidth;
y = (int) canvasHeight;
}
else
{
if (goingRight)
x=x+5;
else
x=x-5;
if (goingDown)
y=y+5;
else
y=y-5;
}
canvas.drawBitmap(ball,x/2,y/2,null);
if (x>canvasWidth)
goingRight=false;
else if (x<0)
goingRight=true;
if (y>canvasHeight)
goingDown=false;
else if (y<0)
{
goingDown=true;
}
flag=false;
Couldn't find a fix for it. anyone knows what is the problem?
Probably because you draw your ball at half x and half y.
canvas.drawBitmap(ball,x/2,y/2,null);
I think you want draw the ball not on top/left corner of the bitmap but on center.
Is not tested ! Try somthing as...
canvas.drawBitmap(ball,x - (ball.getWidth()/2),y - (ball.getHeight()/2),null);
Related
I am creating a playable maze in Three.js. All the objects —the floor, the ceiling and the walls— have been placed within positive X and Z axises. The camera is placed like this:
camera = new THREE.PerspectiveCamera(45,
window.innerWidth / window.innerHeight,
0.1,
1000
);
camera.position.set(0, 0.25, 0);
// The camera is placed pointing to the nearest open path from the
// initial position. Check mazeGenerator.js for the reference of
// "coordinates".
if(grid[1][0] == coordinates.W)
{
camera.lookAt(new THREE.Vector3(1, 0.25, 0));
}
else
{
camera.lookAt(new THREE.Vector3(0, 0.25, 1));
}
and it moves like that:
function keyboardCheck()
{
var movementSpeed = 0.02;
var rotationSpeed = 0.03;
if(keyboard.pressed('w') || keyboard.pressed('up'))
{
camera.translateZ(-movementSpeed);
}
if(keyboard.pressed('a') || keyboard.pressed('left'))
{
camera.rotateY(rotationSpeed);
}
if(keyboard.pressed('d') || keyboard.pressed('right'))
{
camera.rotateY(-rotationSpeed);
}
}
If I place the camera without the lookAt function, it seems that it faces [0, 0, 0], but of course what I wanted to do was help the player a little bit by making the camera face the nearest open path possible.
In order to make it move forward, I have to decrement Z, because otherwise when you hit the "move forward" key it goes backwards. This makes me think that even though I am telling the camera to look at a certain direction, the object's Z axis is opposite to the world's Z axis.
The question itself is: why is this happening?
Thank you very much in advance.
https://github.com/MikelAlejoBR/3D-Maze-95/tree/0.4
https://github.com/MikelAlejoBR/3D-Maze-95/issues/8
The camera is looking down its negative-z axis, so to move forward, do this:
camera.translateZ( - distance );
All other objects are considered to be looking in the direction of their positive-z axis, so to move other objects forward, you would use
object.translateZ( distance );
three.js r.85
I was hoping that I could get some help with the problem that I'm having right now.
Basically I have some bullets, and then I have a group of enemies that move with velocity. The enemies have different sprites and basically I want to assign a value per sprite type. It works, for example, if I say if a diamond is generated and collides with a bullet you get 10 points, but the strange behavior is when it collides, since all enemies on screen give the 10 points and they all get destroyed, not just the one.
Also if the 10 point sprite is not on screen, no points are given which is normal.
Please find my code below and I would appreciate any help given. Thanks.
//here is my bullets group
createBullets: function(){
//Bullets
this.bullets = this.add.group();
this.bullets.enableBody = true;
this.bullets.physicsBodyType = Phaser.Physics.P2JS;
this.bullets.createMultiple(500, 'bullet', 0, false);
this.bullets.setAll('anchor.x', 0.5);
this.bullets.setAll('anchor.y', 0.5);
this.bullets.setAll('outOfBoundsKill', true);
this.bullets.setAll('checkWorldBounds', true);
},
///here are my enemies
addOneFigura: function(x, y) {
this.figuras = this.add.group();
//these are sprites
this.figuritas = ["figura1","figura2","figura3","figura4","figura5","figura6"];
this.figurita = this.figuritas[Math.floor(Math.random()*6)];
this.figura = this.add.sprite(x,y,this.figurita);
this.figuras.add(this.figura);
this.physics.p2.enable(this.figura, false);
this.figura.body.velocity.y = 75;
this.figura.checkWorldBounds = true;
this.figura.outOfBoundsKill = true;
this.figura.body.setCollisionGroup(this.figurasCG);
this.figura.body.collides(this.bulletsCG, this.collisionBulletMatch, this);
},
//and lastly this is my collision function
collisionBulletMatch: function(figurita, figuritapega) {
if (this.figurita != this.figuritapega){
this.score += 10;
this.scoreText.text = this.score;
this.resetFigura();
}
}
So basically when they collide the whole figuras group disappears instead of just the one colliding.
I'll readily admit I haven't done much with P2 physics in Phaser, but the immediate thing that comes to mind is that while you're calling resetFigura you're not passing in a figure (figura). Without seeing the initialization of the variable I can't be sure, but I think you want to change your function to something like the following:
resetFigura: function(figura) {
figura.sprite.kill();
},
This should be called via this.resetFigura(figuritapega); in collisionBulletMatch.
If it's not in the resetFigura call, I would also recommend taking a look at the official P2 Physics collision group example; I was able to get that up and running fairly quickly. It does have a single player character, but if you simplify your bullets to one you might be able to figure out your issue.
I am learning game programming with Phaser and I am currently building a simple breakout game.
When the ball hits the paddle I use the following code to determine the new x velocity of the ball:
if (ball.x < paddle.x)
{
// Ball is on the left-hand side of the paddle
diff = paddle.x - ball.x;
ball.body.velocity.x = (-10 * diff);
}
else if (ball.x > paddle.x)
{
// Ball is on the right-hand side of the paddle
diff = ball.x -paddle.x;
ball.body.velocity.x = (10 * diff);
}
else
{
// Ball is perfectly in the middle
// Add a little random X to stop it bouncing straight up!
ball.body.velocity.x = 2 + Math.random() * 8;
}
This code is originally taken I believe from stackoverflow, although I cannot remember from which post I'm afraid.
The problem with this is that when the ball goes left or right at an angle, it appears faster on screen than if it goes straight up. The more pronounced the angle, the faster it goes and appears.
Does anyone know how to solve this problem?
Regards
Crouz
The speed of the ball is given by a combination of the horizontal (x) speed and vertical (y) speed, as given by Pythagoras' theorem:
z2 = x2 + y2
where overall speed would be z.
If you increase x without decreasing y appropriately, then the overall speed will also increase.
If you want the speed to remain the same, then you need to adjust y as well. Example pseudo-code:
speed = sqrt(x^2 + y^2)
x = 2 + random()*8
y = sqrt(speed^2 - x^2)
You could incorporate this into your code by calculating speed before any adjustments are made, and then adjusting y afterwards:
// Calculate overall speed
var speed = Math.sqrt(
Math.pow(ball.body.velocity.x, 2) +
Math.pow(ball.body.velocity.y, 2)
);
if (ball.x < paddle.x)
{
// Ball is on the left-hand side of the paddle
diff = paddle.x - ball.x;
ball.body.velocity.x = (-10 * diff);
}
else if (ball.x > paddle.x)
{
// Ball is on the right-hand side of the paddle
diff = ball.x -paddle.x;
ball.body.velocity.x = (10 * diff);
}
else
{
// Ball is perfectly in the middle
// Add a little random X to stop it bouncing straight up!
ball.body.velocity.x = 2 + Math.random() * 8;
}
// Adjust y to maintain same overall speed
ball.body.velocity.y = Math.sqrt(
Math.pow(speed, 2) -
Math.pow(ball.body.velocity.x, 2)
);
This will always result in a positive y, so you might need to negate it depending on which direction (up or down) you want it to be moving.
As you see in the picture above, billy, our little orange dressed man, is going off the screen to the left and appearing on the right side.
This is what I want to happen, however, I can't seem to replicate this effect (I got the picture with some modifications in Paint.net).
Basically, if the players x position is negative, it should wrap to the other side. If the x is larger than the width, it should wrap over to the left side.
Draw it two times when you need it.
void Draw(SpriteBacth batch)
{
batch.Draw(Player.texture, Player.Position, player.Source, player.Color);
if (Player.X <0)
{
bacth.Draw(Player.texture, Player.Position + ScreenHorizontalSize, player.Source, Player.Color);
}
else if (Player.X + Player.Size.Width> ScreenHorizontalSize.Width)
{
bacth.Draw(Player.texture, Player.Position - ScreenHorizontalSize, player.Source, Player.Color);
}
}
void Update()
{
if (Player.X < -Player.Size.Width) Player.X += ScreenHorizontalSize.Width;
if (Player.X > ScreenHorizontalSize.Width) Player.X -= ScreenHorizontalSize.Width;
}
Of course you have to take in mind this when you check for colliding with player, you will have to check in the two positions too.
I've got a little text drawing puzzle under Win32. I'm trying to draw some instructions for users of my application at the top of the window.
Please refer to the following window (I've changed the background color on the text so you can see the boundaries)
(source: billy-oneal.com)
I'm currently using DrawTextEx to draw the text to my window, but the problem is that it does not fill the entire RECTangle that I give it. Not drawing that area is just fine, until the window resizes:
(source: billy-oneal.com)
When the text is re wrapped due to the window sizing, because DrawTextEx doesn't clear it's background, these artifacts are leftover.
I tried using FillRect to fill in the area behind the text drawing call, which does eliminate the visual artifacts, but then causes the text to flicker constantly, as it is completely erased and then completely redrawn to the display.
Any ideas on how one might get the area not containing text to be drawn with the background color?
EDIT: I'd like to avoid having to double buffer the form if at app possible.
EDIT2: I solved the problem by only redrawing the text when I detect that the wrapping changes during a resize.
Use double buffering?
Draw everything to a bitmap and draw the bitmap to the window. Flickering is commonly a double buffering issue.
There are many possible solutions and without seeing your code, it's hard to tell which method would be best so I'd suggest taking a look at this article on flicker free drawing
SetBkMode + SetBkColor ?
Well since nobody seems to know what to do about it, I implemented it this way:
std::vector<std::wstring> wrapString(HDC hDC, const std::wstring& text, const RECT& targetRect, HFONT font)
{
std::vector<std::wstring> result;
RECT targetRectangle;
CopyRect(&targetRectangle, &targetRect);
//Calculate the width of the bounding rectangle.
int maxWidth = targetRectangle.right - targetRectangle.left;
//Draw the lines one at a time
std::wstring currentLine;
for(std::wstring::const_iterator it = text.begin(); it != text.end(); currentLine.push_back(*it), it++)
{
if(*it == L'\r' || *it == L'\n')
{ //Hard return
while(it != text.end() && (*it == L'\r' || *it == L'\n')) it++;
result.push_back(currentLine);
currentLine.clear();
}
else
{ //Check for soft return
SIZE sizeStruct;
GetTextExtentPoint32(hDC, currentLine.c_str(), static_cast<int>(currentLine.length()), &sizeStruct);
if (sizeStruct.cx > maxWidth)
{
std::wstring::size_type lineLength = currentLine.find_last_of(L' ');
if (lineLength == currentLine.npos)
{ //Word is longer than a line.
for(;it != text.end() && !iswspace(*it);it++) currentLine.push_back(*it);
}
else
{ //Clip word to line.
//Backtrack our scan of the source text.
it -= currentLine.length() - lineLength - 1;
//Remove the clipped word
currentLine.erase(lineLength);
}
result.push_back(currentLine);
currentLine.clear();
}
}
}
//Last remaining text.
result.push_back(currentLine);
return result;
}
void DrawInstructionsWithFilledBackground(HDC hDC, const std::wstring& text, RECT& targetRectangle, HFONT font, COLORREF backgroundColor)
{
//Set up our background color.
int dcIdx = SaveDC(hDC);
HBRUSH backgroundBrush = CreateSolidBrush(backgroundColor);
SelectObject(hDC, backgroundBrush);
SelectObject(hDC, font);
SetBkColor(hDC, backgroundColor);
std::vector<std::wstring> lines(wrapString(hDC, text, targetRectangle, font));
for(std::vector<std::wstring>::const_iterator it = lines.begin(); it!=lines.end(); it++)
{
RECT backgroundRect = targetRectangle;
DrawText(hDC, const_cast<LPWSTR>(it->c_str()), static_cast<int>(it->length()), &backgroundRect, DT_CALCRECT | DT_NOCLIP | DT_SINGLELINE);
backgroundRect.left = backgroundRect.right;
backgroundRect.right = targetRectangle.right;
if (backgroundRect.right >= backgroundRect.left)
FillRect(hDC, &backgroundRect, backgroundBrush);
ExtTextOut(hDC, targetRectangle.left, targetRectangle.top, ETO_OPAQUE, NULL, it->c_str(), static_cast<UINT>(it->length()), NULL);
targetRectangle.top += backgroundRect.bottom - backgroundRect.top;
}
instructionsWrap = lines;
//Restore the DC to it's former glory.
RestoreDC(hDC, dcIdx);
DeleteObject(backgroundBrush);
}
Get/Calculate the rect used by the DrawText call and clip it with something like ExcludeClipRect before calling FillRect