Can somebody help me with what these lines of code are actually saying?
if (!(x == snakeX && y == snakeY)) batch.draw(texture, x, y);
and
for (BodyPart bodyPart : bodyParts) {
bodyPart.draw(batch);
}
here is what you could say about those lines
if (!(x == snakeX && y == snakeY)) batch.draw(texture, x, y);
if some coordinate* (x,y) are not equal to the snake coordinate
(position of the snake in the screen) then a texture will be drawn in
the screen at the (x,y) position of the screen
for (BodyPart bodyPart : bodyParts) {
bodyPart.draw(batch);
}
drawing all the part of the body of snake which each par is class
named BodyPart
this code refer to the classic game of snake
good luck
Related
I'm trying to write a shader which renders a cube map / cube texture as an equirectangular projection.
The main part of this is done however I get white lines between the faces.
My methodology is:
Starting from UV ([0,1]x[0,1])
Transform to [-1,1]x[-1,1] and than to [-180,180]x[-90,90]
These are now long lat, which can be transformed into 3D (xyz)
Get the face they belong to, as well as their position within this face ([-1,1]x[-1,1])
Transform this face position to a UV within the cube texture
At first I thought the output of step 4 was wrong and that I was sampling from outside the texture, but even after multiplying the face coordinates by 1/2, I still get the white lines.
reference: https://codepen.io/coutteausam/pen/jOKKYYy
float max3(vec3 v) {
return max(max(v.x, v.y), v.z);
}
vec2 sample_cube_map_1(vec3 xyz, out float faceIndex) {
xyz /= length(xyz);
float m = max3(abs(xyz));
if (abs(xyz.x) == m) {
faceIndex = sign(xyz.x);
return xyz.yz / abs(xyz.x);
}
if (abs(xyz.y) == m) {
faceIndex = 2. * sign(xyz.y);
return xyz.xz / abs(xyz.y);
}
if (abs(xyz.z) == m) {
faceIndex = 3. * sign(xyz.z);
return xyz.xy / abs(xyz.z);
}
faceIndex = 1.0;
return vec2(0., 0.);
}
vec2 sample_cube_map(vec3 xyz) {
float face;
vec2 xy = sample_cube_map_1(xyz, face);
xy = (xy + 1.) / 2.; // [-1,1] -> [0,1]
xy.x = clamp(xy.x, 0., 1.);
xy.y = clamp(xy.y, 0., 1.);
if (face == 1.) {
// front
xy += vec2(1., 1.);
}
else if (face == -1.) {
//back
xy.x = 1. - xy.x;
xy += vec2(3., 1.);
}
else if (face == 2.) {
// right
xy.x = 1. - xy.x;
xy += vec2(2., 1.);
}
else if (face == -2.) {
// left
xy += vec2(0., 1.);
}
else if (face == 3.) {
// top
xy = vec2(xy.y, 1. - xy.x);
xy += vec2(1., 2.);
}
else if (face == -3.) {
// bottom
xy = xy.yx;
xy += vec2(1., 0.);
}
else {
xy += vec2(1., 0.);
}
return xy / vec2(4., 3.); // [0,4]x[0,3] -> [0,1]x[0,1]
}
// projects
// uv:([0,1] x [0,1])
// to
// xy:([ -2, 2 ] x [ -1, 1 ])
vec2 uv_2_xy(vec2 uv) {
return vec2(uv.x * 4. - 2., uv.y * 2. - 1.);
}
// projects
// xy:([ -2, 2 ] x [ -1, 1 ])
// to
// longlat: ([ -pi, pi ] x [-pi/2,pi/2])
vec2 xy_2_longlat(vec2 xy) {
float pi = 3.1415926535897932384626433832795;
return xy * pi / 2.;
}
vec3 longlat_2_xyz(vec2 longlat) {
return vec3(cos(longlat.x) * cos(longlat.y), sin(longlat.x) * cos(longlat.y), sin(longlat.y));
}
vec3 uv_2_xyz(vec2 uv) {
return longlat_2_xyz(xy_2_longlat(uv_2_xy(uv)));
}
vec3 roty(vec3 xyz, float alpha) {
return vec3(cos(alpha) * xyz.x + sin(alpha) * xyz.z, xyz.y, cos(alpha) * xyz.z - sin(alpha) * xyz.x);
}
varying vec2 vUv;
uniform sampler2D image;
uniform float time;
void main() {
vec3 xyz = uv_2_xyz(vUv);
xyz = roty(xyz, time);
vec2 uv = sample_cube_map(xyz);
vec4 texturePixel = texture2D(image, vec2(clamp(uv.x, 0., 1.), clamp(uv.y, 0., 1.)));
gl_FragColor = texturePixel;
}
The math behind your shader looks sound. However, you need to consider how texture sampling behaves when dealing with sub-pixels. Take a look at your source texture:
When you cross the boundary between Top to Right, your sampler will try to squeeze all the texture between magenta and teal into a single pixel. Since there's lots of white in that area, that squeezed pixel will be mostly white. Notice this doesn't happen between Top to Front, because there's no white area between those two faces. (Read: mipmapping to see how textures behave when scaled down)
Solutions:
You might be able to sample the nearest full pixel, instead of trying to blend in between them, by turning off mipmapping. To do so, you can change the texture's minification filter to linear filtering.
const imgTexture = new THREE.TextureLoader().load('https://i.imgur.com/tBzfYG5.png');
imgTexture.minFilter = THREE.LinearFilter;
The only downside is that you might get some hard edges along the boundaries.
If your project allows it, you could simply break up your texture into six images, then use the cubemap method offered by Three.js
I have a ball and a player.What should I do to move ball in the direction in which the player hits it?I tried comparing x and y of player and ball. But it didn't work.
You should post some code what have you tried so far...
I think with some if conditions you can decide which should be the ball movement direction. I will give you a hint:
if(player.hitTestObject(ball)) {
//if player hit the ball
//now you should see the possition of ball and of the player
//[we need some variables, you will see for what later on]
var x_direction, y_direction;
if(player.x < ball.x) {
//that means your ball is in the right , and player in the left
//and the ball should change position x with '+' sign --> (you will use this a bit latter when you will move the ball)
//now we will use the x_direction variable to retain the direction in which the ball should move
//because player is in the left (player.x < bal.x) that means the ball should move to right
x_direction = 'right';
}
else {
//it's opposite ....
//because player is in the right (player.x > bal.x) that means the ball should move to left
x_direction = 'left';
}
//now we finished with x...we should check also the y axis
if(player.y < ball.y) {
//that means your ball is below the player
//player hit the ball from the top
y_direction = 'down';
}
else {
//it's opposite ....
//the ball should go up
y_direction = 'up';
}
// now we have to move the ball
// we do this according to possition we checked before
if(x_direction == 'right') {
//you should define your speed somewhere up like var speed = 10;
ball.x = ball.x + speed; // remember the sign '+'?
//or ball.x += speed;
} else {
ball.x -= speed;
}
//and the same with y direction
if(y_direction == 'down') {
//you should define your speed somewhere up like var speed = 10;
ball.y += speed;
} else {
ball.y -= speed;
}
// you can put this movement in an enterframe loop and make the movement....
}
Hope this will help you to make it working...
For my game i wanted to use trigonometry. As i have initialy searched everything was the same as it was in Actionscript3. But i was wrong. Nothing worked as it should. So after searching the libGDX forum and stachoverflow posts i have "played" with numbers and find solution. Hope it helps someone
How to calculate an angle in libgdx and how to set x and y velocity with trigonometry (code omitted for clarity):
//variables
private Object object;
private float touchX, touchY, angle, xSpeed, ySpeed;
private final int power = 5;
//touch up event
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
touchX = screenX;
touchY = h - screenY; // screenX gives an inverted y position (y == 0 is at the top)
setPosition(touchX, touchY);
}
//set angle and velocity method
public void setPosition(int x, int y){
//example 1 (velocity is calculated without angle):
angle = (float) (Math.atan2(y - object.y, x - object.x) * tdg) - 90.0f;
//at the end there is not always -90.0f. It depends of how the texture (or sth else we
//want to rotate) is rotated in .png file. Play with nuber if -90.0f is not good. Use
//the scale from -360 to 360
xSpeed = (x - bx) / 30;
ySpeed = (y - by) / 30;
//example 2 (velocity with angle):
angle = (float) Math.atan2(y - object.y, x - object.x);
xSpeed = (float) (Math.cos(angle)*power);
ySpeed = (float) (Math.sin(angle)*power);
angle = (angle*180/Math.PI) - 90.0f;
}
I have recently been making a game in dart. In the game, the user controls a space ship sprite with the W, A, S and D keys. These will make the sprite move UP. Left, Right and Down respectively. Space will make a square that represents a projectile, missile bullet etc. move at great speed in the direction the ship is facing.
I have a very bad system that works:
(FOR HANDLING KEY PRESS)
bool drawBull = false;
void handleKeyboard(KeyboardEvent event) {
kevent = event.keyCode;
if (kevent == KeyCode.W || kevent == KeyCode.UP){
direction = 'up';
window.console.log('w / up');
}
else if (kevent == KeyCode.A || kevent == KeyCode.LEFT){
direction = 'left';
window.console.log('a / left');
}
else if (kevent == KeyCode.S || kevent == KeyCode.DOWN){
direction = 'down';
window.console.log('s / down');
}
else if (kevent == KeyCode.D || kevent == KeyCode.RIGHT){
direction = 'right';
window.console.log('d / right');
}
else if (kevent == KeyCode.SPACE) {
shotX = lastX; shotY = lastY;
if (direction == 'right') { shotX = shotX + 400; }
if (direction == 'down') { shotY = shotY + 400; }
drawBull = true;
window.console.log('space');
} else {
return null;
}
}
And the draw function itself:
void draw() {
canvas.width = canvas.width;
switch (direction) {
case 'up':
lastY = lastY - 3;
context.drawImage(shipU, lastX, lastY);
if (drawBull) { shotY = shotY - 30; context.fillRect(lastX + 240, shotY, 20, 20); }
break;
case 'left':
lastX = lastX - 3;
context.drawImage(shipL, lastX, lastY);
if (drawBull) { shotX = shotX - 30; context.fillRect(shotX, lastY + 240, 20, 20); }
break;
case 'down':
lastY = lastY + 3;
context.drawImage(shipD, lastX, lastY);
if (drawBull) { shotY = shotY + 30; context.fillRect(lastX + 240, shotY, 20, 20); }
break;
case 'right':
lastX = lastX + 3;
context.drawImage(shipR, lastX, lastY);
if (drawBull) { shotX = shotX + 30; context.fillRect(shotX, lastY + 240, 20, 20); }
break;
default:
return null;
}
}
As you can see, this is a long untidy and tedious method. However, despite all my brain racking I can't think of a system that avoids these many if/switch statements and the idea of writing out the draw image and shooting code for each one.
My actual game will be heavily object orientated of course, so perhaps an object-orientated solution would be helpful.
The code answer given to this question was quite nice, although doesn't fit my needs exactly. So perhaps an adoption of a class like that would work well How to listen to key press repetitively in Dart for games?
Thank you very much for your help!
-Tom W.
Instead of storing directions as strings, you could store the Velocity and/or Rotation of items, and use that for rendering.
You could then store a map of the key vs the velocity change:
var keyHandlers = {
KeyCode.W: new Point(0, 1),
KeyCode.S: new Point(0, -1),
KeyCode.A: new Point(-1, 0),
KeyCode.D: new Point(1, 0),
}
var spritePosition = new Point(0, 0);
void handleKeyboard(KeyboardEvent event) {
if (keyHandlers[event.keyCode])
spritePosition += keyHandlers[event.keyCode];
}
Ultimately, you probably want to actually store a Velocity for the sprite, and use input to increase the velocity; and then "decay" that velocity each frame (to represent gravity/friction, etc.).
If your sprite needs to be rendered at a particular direction, you should store a rotation as well as position and velocity. There's a simple set of slides here that could be useful; and there are also lots of good XNA tutorials out there that will cover building a "GameObject" class to wrap up this state (although XNA is dead, the tutorials are great, and the C# is not a million miles from Dart).
When your ship shoots, you can copy the position and rotation from the ship to the bullet and calculate it's velocity by applying the ships rotation to the starting velocity of your bullet.
There's also a great website by Bob Nystrom at gameprogrammingpatterns.com that I'd recommend reading as you get more into it.
I have the classic balls that move in a line:
class Circle{
float x,y,vx,vy,size;
Circle(float ax,float ay){
x = ax;
y = ay;
size = 5;
vx = random(-.1,.1);
vy = random(-.1,.1);
}
void update(int w,int h){
x += vx;
y += vy;
if(x < 0 || x > w) vx *= -1;
if(y < 0 || y > h) vy *= -1;
}
void draw(){
pushStyle();
noStroke();
fill(0);
ellipse(x,y,size,size);
popStyle();
}
}
However, i don't want them moving in a line.
I want them moving in unregular curves. What can i add? noise? sin? cos?
Many thanks.
You may like to have a look in this page. An easy guide in easing equations with working samples. Note that the same technique may be used for curves in time or space.
edit: forgot to say the website is for flash but anyway is simple enough to understand even if you, as me, has no flash knowledge. And code examples are easily adapted.
Depends on what you want but if you want them to move according to a sinusoidal curve, for example, you could do this:
class Circle{
float x,y,vx,vy,size;
float sinCtr = 0;
// ...
void update(int w,int h){
x += vx;
y = h/2 + 50 * Math.sin(sinCtr);
sinCtr += 0.02;
}