Table table;
Stage stage;
Skin skin;
TextureAtlas atlas;
private BitmapFont black;
OrthographicCamera camera;
private static final int VIRTUAL_WIDTH = 1280;
private static final int VIRTUAL_HEIGHT = 720;
private static final float ASPECT_RATIO = (float)VIRTUAL_WIDTH/(float)VIRTUAL_HEIGHT;
private Rectangle viewport;
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1,1,1,1);
camera.update();
try {
camera.apply(Gdx.gl10);
} catch(Exception e) {
}
// set viewport
Gdx.gl.glViewport((int) viewport.x, (int) viewport.y,
(int) viewport.width, (int) viewport.height);
// clear previous frame
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
Table.drawDebug(stage);
stage.draw();
}
#Override
public void resize(int width, int height) {
// calculate new viewport
float aspectRatio = (float)width/(float)height;
float scale = 1f;
Vector2 crop = new Vector2(0f, 0f);
if(aspectRatio > ASPECT_RATIO)
{
scale = (float)height/(float)VIRTUAL_HEIGHT;
crop.x = (width - VIRTUAL_WIDTH*scale)/2f;
}
else if(aspectRatio < ASPECT_RATIO)
{
scale = (float)width/(float)VIRTUAL_WIDTH;
crop.y = (height - VIRTUAL_HEIGHT*scale)/2f;
}
else
{
scale = (float)width/(float)VIRTUAL_WIDTH;
}
float w = (float)VIRTUAL_WIDTH*scale;
float h = (float)VIRTUAL_HEIGHT*scale;
viewport = new Rectangle(crop.x, crop.y, w, h);
}
#Override
public void show() {
stage = new Stage();
camera = new OrthographicCamera(VIRTUAL_WIDTH, VIRTUAL_HEIGHT);
black = new BitmapFont(Gdx.files.internal("data/font.fnt"), false);
atlas = new TextureAtlas("data/button.pack");
skin = new Skin(atlas);
table = new Table(skin);
table.setPosition(50, Gdx.graphics.getHeight()-(Gdx.graphics.getHeight()-50));
table.setSize(Gdx.graphics.getWidth()-100, Gdx.graphics.getHeight()-100);
LabelStyle style = new LabelStyle();
style.font = black;
table.align(Align.top);
Label label = new Label("ORTHO", style);
label.setWrap(true);
label.setAlignment(Align.left);
Label label1 = new Label("A", style);
label1.setWrap(true);
label1.setAlignment(Align.center);
Label label2 = new Label("B", style);
label2.setWrap(true);
label2.setAlignment(Align.center);
Label label3 = new Label("C", style);
label3.setWrap(true);
label3.setAlignment(Align.center);
table.add(label).width(Gdx.graphics.getWidth()-100).colspan(3).align(Align.left).padBottom(50);
table.row();
table.add(label1).width((Gdx.graphics.getWidth()-100)/3).height((Gdx.graphics.getWidth()-100)/3);
table.add(label2).width((Gdx.graphics.getWidth()-100)/3).height((Gdx.graphics.getWidth()-100)/3);
table.add(label3).width((Gdx.graphics.getWidth()-100)/3).height((Gdx.graphics.getWidth()-100)/3);
table.row();
table.add(label1).width((Gdx.graphics.getWidth()-100)/3).height((Gdx.graphics.getWidth()-100)/3);
table.add(label2).width((Gdx.graphics.getWidth()-100)/3).height((Gdx.graphics.getWidth()-100)/3);
table.add(label3).width((Gdx.graphics.getWidth()-100)/3).height((Gdx.graphics.getWidth()-100)/3);
table.row();
table.add(label1).width((Gdx.graphics.getWidth()-100)/3).height((Gdx.graphics.getWidth()-100)/3);
table.add(label2).width((Gdx.graphics.getWidth()-100)/3).height((Gdx.graphics.getWidth()-100)/3);
table.add(label3).width((Gdx.graphics.getWidth()-100)/3).height((Gdx.graphics.getWidth()-100)/3);
table.debug();
stage.addActor(table);
TextButtonStyle textButtonStyle = new TextButtonStyle();
textButtonStyle.up = skin.getDrawable("button.up");
textButtonStyle.down = skin.getDrawable("button.down");
textButtonStyle.pressedOffsetX = 1;
textButtonStyle.pressedOffsetY = -1;
textButtonStyle.font = black;
textButtonStyle.font.setScale(3);
TextButton button = new TextButton("game", textButtonStyle);
button.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("hello");
return false;
}
});
}
i'm expecting the table i'm creating with this code to fit the screen, and it does perfectly on my Galaxy S3, i've added the
private Rectangle viewport;
....
....
Gdx.gl.glClearColor(1,1,1,1);
camera.update();
try {
camera.apply(Gdx.gl10);
} catch(Exception e) {
}
....
....
// set viewport
Gdx.gl.glViewport((int) viewport.x, (int) viewport.y,
(int) viewport.width, (int) viewport.height);
....
....
float aspectRatio = (float)width/(float)height;
float scale = 1f;
Vector2 crop = new Vector2(0f, 0f);
if(aspectRatio > ASPECT_RATIO)
{
scale = (float)height/(float)VIRTUAL_HEIGHT;
crop.x = (width - VIRTUAL_WIDTH*scale)/2f;
}
else if(aspectRatio < ASPECT_RATIO)
{
scale = (float)width/(float)VIRTUAL_WIDTH;
crop.y = (height - VIRTUAL_HEIGHT*scale)/2f;
}
else
{
scale = (float)width/(float)VIRTUAL_WIDTH;
}
float w = (float)VIRTUAL_WIDTH*scale;
float h = (float)VIRTUAL_HEIGHT*scale;
viewport = new Rectangle(crop.x, crop.y, w, h);
....
....
camera = new OrthographicCamera(VIRTUAL_WIDTH, VIRTUAL_HEIGHT);
to scale it properly to other devices like a 480-320 emulator i have running, but it doesn't at all, it scales it fine, but puts the table way lower then where it should be...
Related
So I'm making a game where the enemies follow the player and the player kills them. How do I make the enemies' ImageViews follow the player.
I have tried some if sentences but I actually have no idea. I also searched everywhere but I only find other people doing it with Swing and I get really confused with a lot of things. I use Javafx btw.
public class Main extends Application{
private static final int HEIGHT = 720;
private static final int WIDTH = 1280;
Scene scene;
BorderPane root, htpLayout;
VBox buttons, paragraphs, images;
Button startButton, htpButton, htpReturnButton, leaderboardButton, exitButton;
Text gameName, paragraph1, paragraph2, paragraph3;
Pane gameLayout;
ImageView background;
Game game = new Game();
Player player = new Player();
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage window) throws Exception {
root = new BorderPane();
background = new ImageView("stick mob slayer background.png");
background.fitWidthProperty().bind(window.widthProperty());
background.fitHeightProperty().bind(window.heightProperty());
root.getChildren().add(background);
htpLayout = new BorderPane();
buttons = new VBox(15);
scene = new Scene(root, WIDTH, HEIGHT);
scene.getStylesheets().add("mobslayer/style.css");
gameName = new Text("Mob Slayer Unlimited");
gameName.setFont(Font.font("Complex", 50));
gameName.setFill(Color.WHITE);
root.setAlignment(gameName, Pos.CENTER_LEFT);
root.setTop(gameName);
startButton = new Button("Start Game");
startButton.setOnAction(e -> window.setScene(game.getScene()));
htpButton = new Button("How To Play");
htpButton.setOnAction(e -> scene.setRoot(htpLayout));
leaderboardButton = new Button("Leaderboard");
exitButton = new Button("Exit");
exitButton.setOnAction(e -> Platform.exit());
buttons.getChildren().addAll(startButton, htpButton, leaderboardButton, exitButton);
root.setCenter(buttons);
buttons.setAlignment(Pos.CENTER);
paragraphs = new VBox(30);
paragraph1 = new Text("Objektive\nNär spelet börjar kommer huvudkaraktären möta monster.\n"
+ "Ju längre in i spelet du kommer, ju fler och svårare monster dyker upp.\n"
+ "Ditt mål är att överleva så länge som möjligt.");
paragraph1.setFont(Font.font("Dubai", 13));
paragraph1.setFill(Color.BLACK);
paragraph2 = new Text("Movement\nAlla monster dras imot dig, så du måste akta dig.\n"
+ "Detta gör du med hjälp av piltangenterna.");
paragraph2.setFont(Font.font("Dubai", 13));
paragraph2.setFill(Color.BLACK);
paragraph3 = new Text("Special Effects\nDu kan också attackera tillbaka med en lätt attack(c)\n"
+ "eller med en specialattack(space) som dödar alla monster på skärmen.\n"
+ "Du kan dasha(x) för att röra dig snabbare åt ett håll.");
paragraph3.setFont(Font.font("Dubai", 13));
paragraph3.setFill(Color.BLACK);
paragraphs.getChildren().addAll(paragraph1, paragraph2, paragraph3);
htpReturnButton = new Button("Return");
htpReturnButton.setOnAction(e->scene.setRoot(root));
htpLayout.setBottom(htpReturnButton);
htpLayout.setAlignment(htpReturnButton,Pos.TOP_CENTER);
images = new VBox(30);
// Image image1 = new Image(new FileInputStream("resources\\cod zombies.jpg"));
// final ImageView image11 = new ImageView(image1);
// image11.setFitHeight(100);
// image11.setFitWidth(100);
// image11.setPreserveRatio(true);
//
// Image image2 = new Image(new FileInputStream("resources\\arrowkeys.png")) ;
// final ImageView image22 = new ImageView(image2);
// image22.setFitHeight(100);
// image22.setFitWidth(100);
// image22.setPreserveRatio(true);
//
// Image image3 = new Image(new FileInputStream("resources\\keys.png")) ;
// final ImageView image33 = new ImageView(image3);
// image33.setFitHeight(100);
// image33.setFitWidth(100);
// image33.setPreserveRatio(true);
//
// images.getChildren().addAll(image11, image22, image33);
//
paragraphs.setAlignment(Pos.TOP_LEFT);
htpLayout.setLeft(paragraphs);
htpLayout.setRight(images);
window.setTitle("Mob Slayer Unlimited");
window.setScene(scene);
window.setResizable(false);
window.show();
}
}
public class Game {
private static final int HEIGHT = 720;
private static final int WIDTH = 1280;
private Scene scene;
Pane root;
Text health, stamina, wave, kills;
int waveCounter = 1, killCounter = 0;
Button restartButton, pauseButton;
Line limitUp;
Player player = new Player();
Enemies enemy = new Enemies();
public Game() {
health = new Text(50, 30, "HP: " + player.getHealth());
health.setFont(Font.font("BankGothic Lt BT", 30));
health.setFill(Color.WHITE);
stamina = new Text(50, 80, "STAMINA: " + player.getStamina());
stamina.setFont(Font.font("BankGothic Lt BT", 30));
stamina.setFill(Color.WHITE);
wave = new Text(1050, 30, "WAVE: " + waveCounter);
wave.setFont(Font.font("BankGothic Lt BT", 30));
wave.setFill(Color.WHITE);
kills = new Text(1050, 80, "KILLS: " + killCounter);
kills.setFont(Font.font("BankGothic Lt BT", 30));
kills.setFill(Color.WHITE);
restartButton = new Button("RESTART");
restartButton.setFont(Font.font("BankGothic Lt BT", 30));
restartButton.setOnAction(e -> restart());
restartButton.setLayoutX(350);
restartButton.setLayoutY(20);
pauseButton = new Button("PAUSE");
pauseButton.setFont(Font.font("BankGothic Lt BT", 30));
pauseButton.setOnAction(e -> restart());
pauseButton.setLayoutX(650);
pauseButton.setLayoutY(20);
limitUp = new Line(0, 100, 1280, 100);
limitUp.setStroke(Color.WHITE);
root = new Pane(player.getSlayer(), limitUp, player.getSlayerHitbox(), health, stamina, wave, kills, restartButton, pauseButton, enemy.getEnemy());
root.setStyle("-fx-background-color: black");
enemy.enemyMovement();
movePlayerTo(WIDTH / 2, HEIGHT / 2);
scene = new Scene(root, WIDTH, HEIGHT);
scene.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
switch (event.getCode()) {
case W: player.goUp = true; break;
case S: player.goDown = true; break;
case A: player.goLeft = true; break;
case D: player.goRight = true; break;
case K: player.running = true; break;
}
}
});
scene.setOnKeyReleased(new EventHandler<KeyEvent>() {
#Override
public void handle(KeyEvent event) {
switch (event.getCode()) {
case W: player.goUp = false; break;
case S: player.goDown = false; break;
case A: player.goLeft = false; break;
case D: player.goRight = false; break;
case K: player.running = false; break;
}
}
});
AnimationTimer timer = new AnimationTimer() {
#Override
public void handle(long now) {
int dx = 0, dy = 0;
if (player.goUp) dy -= 2;
if (player.goDown) dy += 2;
if (player.goRight) dx += 2;
if (player.goLeft) dx -= 2;
if (player.running) { dx *= 2; dy *= 2; }
enemy.enemyMovement();
movePlayerBy(dx, dy);
}
};
timer.start();
}
public Scene getScene() {
return scene;
}
// I took this methods for movement from Github
public void movePlayerBy(int dx, int dy) {
if (dx == 0 && dy == 0) return;
final double cx = player.getSlayer().getBoundsInLocal().getWidth() / 2;
final double cy = player.getSlayer().getBoundsInLocal().getHeight() / 2;
double x = cx + player.getSlayer().getLayoutX() + dx;
double y = cy + player.getSlayer().getLayoutY() + dy;
movePlayerTo(x, y);
}
public void movePlayerTo(double x, double y) {
final double cx = player.getSlayer().getBoundsInLocal().getWidth() / 2;
final double cy = player.getSlayer().getBoundsInLocal().getHeight() / 2;
if (x - cx >= 0 &&
x + cx <= WIDTH &&
y - cy >= 0 &&
y + cy <= HEIGHT) {
player.getSlayer().relocate(x - cx, y - cy);
player.getSlayerHitbox().relocate(x - cx + 37, y - cy + 35);
}
}
public class Player {
private int health;
private int damage;
private int stamina;
private Image slayerImage;
private ImageView slayer;
private Rectangle slayerHitbox;
boolean running, goUp, goDown, goRight, goLeft;
public Player () {
health = 5;
damage = 1;
stamina = 5;
slayerImage = new Image("stick mob slayer.png", 100, 100, true, true);
slayer = new ImageView(slayerImage);
slayerHitbox = new Rectangle(10, 50);
}
public int getDamage() {
return damage;
}
public void setDamage(int damage) {
this.damage = damage;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getStamina() {
return stamina;
}
public void setStamina(int stamina) {
this.stamina = stamina;
}
public ImageView getSlayer() {
return slayer;
}
public Rectangle getSlayerHitbox() {
slayerHitbox.setFill(Color.TRANSPARENT);
return slayerHitbox;
}
}
public class Enemies {
private int health;
private int speed;
private Image enemyImage;
private ImageView enemy;
private Rectangle enemyHitbox;
Player player = new Player();
public Enemies () {
health = 1;
speed = 1;
enemyImage = new Image("stick enemy.png", 100, 100, true, true);
enemy = new ImageView(enemyImage);
enemyHitbox = new Rectangle(10, 50);
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getSpeed() {
return speed;
}
public void setSpeed(int speed) {
this.speed = speed;
}
public ImageView getEnemy () {
return enemy;
}
public Rectangle getEnemyHitbox() {
enemyHitbox.setFill(Color.YELLOW);
return enemyHitbox;
}
}
This is everything I have done so far. I would appreciate any help. If possible I would like to know how to make the enemies appear from random spots of the borders of the screen as well. Thanks in advance.
you should try first something more simple like implementing A* path search algo or some grid with some units on it before trying todo a game and having such questions
FaceView.java
package com.example.richelle.neeuro;
public class FaceView extends View {
private float radius;
NormalFace normalFace;
HappyFace happyFace;
public FaceView(Context context, AttributeSet attrs) {
super(context, attrs);
// get radius value
TypedArray a = context.getTheme().obtainStyledAttributes(
attrs,
R.styleable.FaceView,
0, 0
);
try {
radius = a.getDimension(R.styleable.FaceView_radius, 20.0f);
} finally {
a.recycle();
}
// initiate HappyFace class
normalFace = new NormalFace(radius);
happyFace = new HappyFace(radius);
}
Handler setDelay;
Runnable startDelay;
#Override
protected void onDraw(final Canvas canvas) {
super.onDraw(canvas);
normalFace.draw(canvas);
//delay timer
setDelay = new Handler();
startDelay = new Runnable() {
#Override
public void run() {
happyFace.draw(canvas);
}
};
setDelay.postDelayed(startDelay,5000);
}
#Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
int desiredWidth = (int) radius*2+(int) Math.ceil((radius/1.70));
int desiredHeight = (int) radius*2+(int)Math.ceil((radius/1.70));
int widthMode = MeasureSpec.getMode(widthMeasureSpec);
int widthSize = MeasureSpec.getSize(widthMeasureSpec);
int heightMode = MeasureSpec.getMode(heightMeasureSpec);
int heightSize = MeasureSpec.getSize(heightMeasureSpec);
int width;
int height;
//Measure Width
if (widthMode == MeasureSpec.EXACTLY) {
//Must be this size
width = widthSize;
} else if (widthMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
width = Math.min(desiredWidth, widthSize);
Log.d("Width AT_MOST", "width: "+width);
} else {
//Be whatever you want
width = desiredWidth;
Log.d("Width ELSE", "width: "+width);
}
//Measure Height
if (heightMode == MeasureSpec.EXACTLY) {
//Must be this size
height = heightSize;
} else if (heightMode == MeasureSpec.AT_MOST) {
//Can't be bigger than...
height = Math.min(desiredHeight, heightSize);
} else {
//Be whatever you want
height = desiredHeight;
}
//MUST CALL THIS
setMeasuredDimension(width, height);
}
public float getRadius() {
return radius;
}
public void setRadius(float radius) {
this.radius = radius;
}
}
NormalFace.java
public class NormalFace {
//Paint object
Paint facePaint;
Paint mePaint;
float radius;
float adjust;
float mouthLeftX, mouthRightX, mouthTopY, mouthBottomY;
RectF mouthRectF;
Path mouthPath;
float eyeLeftX, eyeRightx, eyeTopY, eyeBottomY;
RectF eyeLeftRectF, eyeRightRectF;
public NormalFace(float radius){
this.radius= radius;
facePaint = new Paint();
facePaint.setColor(0xfffed325); // face color - yellow
facePaint.setDither(true);
facePaint.setStrokeJoin(Paint.Join.ROUND);
facePaint.setStrokeCap(Paint.Cap.ROUND);
facePaint.setPathEffect(new CornerPathEffect(10) );
facePaint.setAntiAlias(true);
facePaint.setShadowLayer(4, 2, 2, 0x80000000);
mePaint = new Paint();
mePaint.setColor(0xff2a2a2a); //black
mePaint.setDither(true);
mePaint.setStyle(Paint.Style.STROKE);
mePaint.setStrokeJoin(Paint.Join.ROUND);
mePaint.setStrokeCap(Paint.Cap.ROUND);
mePaint.setPathEffect(new CornerPathEffect(10) );
mePaint.setAntiAlias(true);
mePaint.setStrokeWidth(radius / 14.0f);
adjust = radius / 3.2f;
// Left Eye
eyeLeftX = radius-(radius*0.43f);
eyeRightx = eyeLeftX + (radius*0.3f);
eyeTopY = radius-(radius*0.5f);
eyeBottomY = eyeTopY + (radius*0.4f);
eyeLeftRectF = new RectF(eyeLeftX+adjust,eyeTopY+adjust,eyeRightx+adjust,eyeBottomY+adjust);
// Right Eye
eyeLeftX = eyeRightx + (radius*0.3f);
eyeRightx = eyeLeftX + (radius*0.3f);
eyeRightRectF = new RectF(eyeLeftX+adjust,eyeTopY+adjust,eyeRightx+adjust,eyeBottomY+adjust);
// Mouth
mouthLeftX = radius-(radius/2.0f);
mouthRightX = mouthLeftX+ radius;
// mouthTopY = 125 - (125*0.01f);
// mouthBottomY = mouthTopY + (125*0.01f);
mouthTopY = radius - (radius*(-0.2f));
mouthBottomY = mouthTopY + (radius*0.01f);
mouthRectF = new RectF(mouthLeftX+adjust,mouthTopY+adjust,mouthRightX+adjust,mouthBottomY+adjust);
//mouthRectF = new RectF(mouthLeftX+adjust,mouthTopY+70,mouthRightX+adjust,mouthBottomY+20); //a line
mouthPath = new Path();
mouthPath.arcTo(mouthRectF, 30, 120, true);
// mouthPath.arcTo(mouthRectF, 15, 135, true);
}
public void draw(Canvas canvas) {
// 1. draw face
canvas.drawCircle(radius+adjust, radius+adjust, radius, facePaint);
// 2. draw mouth
mePaint.setStyle(Paint.Style.STROKE);
canvas.drawPath(mouthPath, mePaint);
//canvas.drawLine(90, 155, 176, 155, mePaint);
// 3. draw eyes
mePaint.setStyle(Paint.Style.FILL);
canvas.drawArc(eyeLeftRectF, 0, 360, true, mePaint);
canvas.drawArc(eyeRightRectF, 0, 360, true, mePaint);
}
}
HappyFace.java
public class HappyFace {
//Paint object
Paint facePaint;
Paint mePaint;
float radius;
float adjust;
float mouthLeftX, mouthRightX, mouthTopY, mouthBottomY;
RectF mouthRectF;
Path mouthPath;
float eyeLeftX, eyeRightx, eyeTopY, eyeBottomY;
RectF eyeLeftRectF, eyeRightRectF;
public HappyFace(float radius){
this.radius= radius;
facePaint = new Paint();
facePaint.setColor(0xfffed325); // face color - yellow
facePaint.setDither(true);
facePaint.setStrokeJoin(Paint.Join.ROUND);
facePaint.setStrokeCap(Paint.Cap.ROUND);
facePaint.setPathEffect(new CornerPathEffect(10) );
facePaint.setAntiAlias(true);
facePaint.setShadowLayer(4, 2, 2, 0x80000000);
mePaint = new Paint();
mePaint.setColor(0xff2a2a2a); //black
mePaint.setDither(true);
mePaint.setStyle(Paint.Style.STROKE);
mePaint.setStrokeJoin(Paint.Join.ROUND);
mePaint.setStrokeCap(Paint.Cap.ROUND);
mePaint.setPathEffect(new CornerPathEffect(10) );
mePaint.setAntiAlias(true);
mePaint.setStrokeWidth(radius / 14.0f);
adjust = radius / 3.2f;
// Left Eye
eyeLeftX = radius-(radius*0.43f);
eyeRightx = eyeLeftX + (radius*0.3f);
eyeTopY = radius-(radius*0.5f);
eyeBottomY = eyeTopY + (radius*0.4f);
eyeLeftRectF = new RectF(eyeLeftX+adjust,eyeTopY+adjust,eyeRightx+adjust,eyeBottomY+adjust);
// Right Eye
eyeLeftX = eyeRightx + (radius*0.3f);
eyeRightx = eyeLeftX + (radius*0.3f);
eyeRightRectF = new RectF(eyeLeftX+adjust,eyeTopY+adjust,eyeRightx+adjust,eyeBottomY+adjust);
// Smiley Mouth
mouthLeftX = radius-(radius/2.0f);
mouthRightX = mouthLeftX+ radius;
mouthTopY = radius - (radius*0.2f);
mouthBottomY = mouthTopY + (radius*0.5f);
mouthRectF = new RectF(mouthLeftX+adjust,mouthTopY+adjust,mouthRightX+adjust,mouthBottomY+adjust);
mouthPath = new Path();
mouthPath.arcTo(mouthRectF, 30, 120, true);
}
public void draw(Canvas canvas) {
// 1. draw face
canvas.drawCircle(radius+adjust, radius+adjust, radius, facePaint);
// 2. draw mouth
mePaint.setStyle(Paint.Style.STROKE);
canvas.drawPath(mouthPath, mePaint);
// 3. draw eyes
mePaint.setStyle(Paint.Style.FILL);
canvas.drawArc(eyeLeftRectF, 0, 360, true, mePaint);
canvas.drawArc(eyeRightRectF, 0, 360, true, mePaint);
}
}
FaceView.java is to display the different facial expressions in the canvas. The NormalFace.java and HappyFace.java are the UI of the different facial expressions. I want to add a delay timer in FaceView.java so that the display of the normal face can be change to a happy face after the timer had finished counting down.
Use this: ms is delay in millisecond
try {
Thread.sleep(ms);
} catch (InterruptedException e) {
e.printStackTrace();
}
You can use Handler class for this in android.Handler has a method postDelayed(),you can use this method for the delay,read about handler from here
Runnable happy = new Runnable() {
public void run() {
happyFace(); //suppose this is the method for happy face
}
};
and then call this method like this after 5 sec
handler.postDelayed(happy,5000);
It will post your code to be run after 5 sec
You can use Handler to delay your next task
import android.os.Handler;
Handler handler=new Handler();
Runnable r=new Runnable() {
public void run() {
// Your next task
}
};
handler.postDelayed(r, 30000);
30000 is the value of delay in milli seconds which makes it 30 secs
I have a class called Badge (extends Image). It is an Arraylist of 4 elements (image of a cartoon tree). I put them in the stage with touchDown listener to print out "touched" via Gdx.input.setInputProcessor(stage). It works fine. Then I want to click on each tree and it return the index of the tree by using System.out.println("Badge name is: " + event.getRelatedActor().getName());
The app crashed. Any idea why this is happening?
public class PlayScreen implements Screen {
int scWidth, scHeight;
int playerWidth, playerHeight;
Stage stage;
Skin skin;
BitmapFont font;
private SpriteBatch batch; // This is in the render.
ArrayList<Badge> badges;
Iterator<Badge> badgeIterator;
int badgeWidth = 160;
int badgeHeight = 300;
// Create a constructor
Game game;
public PlayScreen(Game game){
this.game = game;
}
// Create a button to randomise tree positions
TextureAtlas buttonAtlas;
TextButton.TextButtonStyle buttonStyle;
TextButton playButton;
int randomBadgePosition(String choice)
{
int min, max, range;
if (choice == "x") {
min = scWidth / 2 - scHeight / 2;
max = scWidth / 2 + scHeight / 2 - badgeWidth;
range = (max - min) + 1;
return (int) (Math.random() * range) + min;
} else{
min = 0;
max = scHeight - badgeHeight;
range = (max - min) + 1;
return (int)(Math.random() * range) + min;
}
}
#Override
public void show() {
batch = new SpriteBatch();
stage = new Stage();
scWidth = Gdx.graphics.getWidth();
scHeight = Gdx.graphics.getHeight();
font = new BitmapFont();
font.setColor(Color.BLACK);
font.getData().setScale(5);
badges = new ArrayList<Badge>();
int numBadges = 4;
for (int i = 0; i < numBadges; i ++){
badges.add(new Badge(new Vector2(-400, -400),new Vector2(badgeWidth, badgeHeight) ));
}
// -------------------
skin = new Skin();
buttonAtlas = new TextureAtlas("buttons/button1.txt");
skin.addRegions(buttonAtlas); // You need to do that.
buttonStyle = new TextButton.TextButtonStyle();
buttonStyle.up = skin.getDrawable("button");
buttonStyle.over = skin.getDrawable("buttonpressed"); // over is not necessary for android.
buttonStyle.down = skin.getDrawable("buttonpressed");
buttonStyle.font = font;
playButton = new TextButton("play", buttonStyle);
playButton.setPosition(50, 20);
stage.addActor(playButton);
//
for (int i = 0; i < numBadges; i ++){
stage.addActor(badges.get(i));
}
Gdx.input.setInputProcessor(stage);
for (int i = 0; i < numBadges; i++) {
badges.get(i).addListener(new InputListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("Badge name is: " + ((Badge)event.getRelatedActor()).getName());
return true;
}
});
}
// Input listener for buttons.
playButton.addListener(new InputListener(){
#Override
public boolean touchDown (InputEvent event, float x, float y,
int pointer, int button){
int tempX, tempY;
// Randomise the locations of the badges.
for (int i = 0; i < badges.size(); i++){
tempX = randomBadgePosition("x");
tempY = randomBadgePosition("y");
badges.get(i).setBounds(tempX, tempY, badgeWidth, badgeHeight);
// badges.get(i).setPosition(new Vector2(tempX, tempY));
}
return true;
}
});
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.end();
stage.act();
stage.draw();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
The Badge class is:
public class Badge extends Image {
Vector2 position, size;
Texture badge;
Rectangle bounds;
public Badge(Vector2 position, Vector2 size){
super(new Texture(Gdx.files.internal("tree.png")));
this.position = position;
this.size = size;
bounds = new Rectangle(position.x, position.y, size.x, size.y);
super.setPosition(position.x, position.y);
super.setSize(size.x, size.y);
}
}
I am developing an off road game, and I am new to libgdx.
I made a car, with only 3 parts: chassis, rear & front wheel. I got a "Zoomable" camera bind with chassis, chassis connected to wheels with Wheel Joint.
Chassis works fine with texture but not wheels.
Here's the problems:
I can't figure out how to calculate the √(correct) vector2 of wheels to put it in the [Sprite.setPosition] method
How to make my car faster cause it never >94
Focus.java
public class Focus extends InputAdapter {
private Body chassis, rearWheel, frontWheel;
private WheelJoint leftAxis, rightAxis;
private float speed = 90f;
private Sprite spriteChassis, spriteRearWheel, spriteFrontWheel;
private float xOffSet = 5f;
private float yOffSet = -2f;
private float rwOffSet = 0;
private float fwOffSet = 0;
private float rwOffSetY = 0;
private float fwOffSetY = 0;
public float getOffSetX(){ return xOffSet; }
public float getOffSetY(){ return yOffSet; }
public Focus(World world, FixtureDef chassisFixtureDef, FixtureDef wheelFixtureDef, float x, float y) {
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(x,y);
bodyDef.gravityScale = 1;
float width = 5.333f;
float height = 1.933f;
BodyEditorLoader loader = new BodyEditorLoader(Gdx.files.internal("data/focus.json"));
chassis = world.createBody(bodyDef);
loader.attachFixture(chassis, "focus", chassisFixtureDef, width);
String imgpath = loader.getImagePath("focus");
chassis.createFixture(chassisFixtureDef);
chassis.setGravityScale(1.2f);
spriteChassis = new Sprite(new Texture(imgpath));
spriteRearWheel = new Sprite(new Texture("tires.png"));
spriteFrontWheel = new Sprite(new Texture("tires.png"));
// Wheels
CircleShape wheelShape = new CircleShape();
wheelShape.setRadius(height / 6f);
wheelFixtureDef.shape = wheelShape;
rearWheel = world.createBody(bodyDef);
rearWheel.createFixture(wheelFixtureDef);
frontWheel = world.createBody(bodyDef);
frontWheel.createFixture(wheelFixtureDef);
// Axels
WheelJointDef axisDef = new WheelJointDef();
axisDef.bodyA = chassis;
axisDef.bodyB = rearWheel;
rwOffSet = wheelShape.getRadius()*3.3f;
axisDef.localAnchorA.x = rwOffSet;
rwOffSetY = height/10.5f;
axisDef.localAnchorA.y = rwOffSetY;
axisDef.frequencyHz = chassisFixtureDef.density;
axisDef.localAxisA.set(Vector2.Y);
axisDef.maxMotorTorque = chassisFixtureDef.density * 24.5f;
leftAxis = (WheelJoint) world.createJoint(axisDef);
// right
// Axels
WheelJointDef axisDef2 = new WheelJointDef();
axisDef2.bodyA = chassis;
axisDef2.bodyB = frontWheel;
axisDef2.localAnchorA.set(width, 0);
axisDef2.frequencyHz = chassisFixtureDef.density;
axisDef2.localAxisA.set(Vector2.Y);
fwOffSet = width-wheelShape.getRadius()*3.f;
axisDef2.localAnchorA.x = fwOffSet;
fwOffSetY = height/9f;
axisDef.localAnchorA.y = fwOffSetY;
axisDef2.maxMotorTorque = chassisFixtureDef.density * 24.5f;
rightAxis = (WheelJoint) world.createJoint(axisDef2);
}
#Override
public boolean keyDown(int keycode) {
switch(keycode) {
case Input.Keys.W:
leftAxis.enableMotor(false);
rightAxis.enableMotor(true);
rightAxis.setMotorSpeed(-speed);
break;
case Input.Keys.S:
leftAxis.enableMotor(false);
rightAxis.enableMotor(true);
rightAxis.setMotorSpeed(speed);
break;
case Input.Keys.SPACE:
leftAxis.enableMotor(true);
leftAxis.setMotorSpeed(0);
rightAxis.enableMotor(true);
rightAxis.setMotorSpeed(0);
break;
}
return true;
}
#Override
public boolean keyUp(int keycode) {
switch(keycode) {
case Input.Keys.SPACE:
case Input.Keys.W:
case Input.Keys.S:
leftAxis.enableMotor(false);
rightAxis.enableMotor(false);
break;
}
return true;
}
public Sprite getSpriteChassis(){ return spriteChassis; }
public Sprite getSpriteRearWheel() { return spriteRearWheel; }
public Sprite getSpriteFrontWheel() { return spriteFrontWheel; }
public Body getChassis() { return chassis; }
public Body getFrontWheel() { return frontWheel; }
public Body getRearWheel() { return rearWheel; }
}
SmallHill.java (Screen)
public class SmallHill implements Screen {
private final float PIXELS_PER_METER = 15f; // how many pixels to a meter
private final float TIME_STEP = 1 / 60f; // 60 fps
private final float SPEED = 1 / 60f; // speed constant
private final float MIN_ZOOM = .25f; // How far in should we be able to zoom
private final float ANGULAR_MOMENTUM = .5f;
private final int VELOCITY_ITERATIONS = 8; // copied from box2d example
private final int POSITION_ITERATIONS = 3; // copied from box2d example
private World world;
private Box2DDebugRenderer debugRenderer;
private OrthographicCamera camera;
private Body ball;
private Focus focus;
private BitmapFont font;
private SpriteBatch batch;
private Texture texture;
#Override
public void show() {
batch = new SpriteBatch();
font = new BitmapFont();
font.setColor(Color.RED);
world = new World(new Vector2(0, -9.81f), true);
debugRenderer = new Box2DDebugRenderer();
camera = new OrthographicCamera();
camera.zoom = 1f;
BodyDef bodyDef = new BodyDef();
// Shape
ChainShape groundShape = new ChainShape();
groundShape.createChain(new Vector2[] {new Vector2(-1,24),new Vector2(0,14),new Vector2(25,14),new Vector2(50,10),new Vector2(100,5),new Vector2(150,12),new Vector2(155,10), new Vector2(200,22),new Vector2(225,22),new Vector2(226,22.15f),new Vector2(227,22),new Vector2(229,22.25f),new Vector2(350,22),new Vector2(385,24),new Vector2(389,25),new Vector2(390,24),new Vector2(395,25),new Vector2(398,24),new Vector2(400,25),new Vector2(401,48) });
CircleShape ballShape = new CircleShape();
ballShape.setRadius(1f);
ballShape.setPosition(new Vector2(-10, 16));
// Fixture
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = groundShape;
fixtureDef.friction = .8f;
fixtureDef.restitution = 0;
world.createBody(bodyDef).createFixture(fixtureDef);
fixtureDef.shape = ballShape;
fixtureDef.friction = 0.9f;
fixtureDef.restitution = .3f;
fixtureDef.density = 3;
bodyDef.type = BodyType.DynamicBody;
fixtureDef.density = 5;
fixtureDef.friction = .4f;
fixtureDef.restitution = .1f;
FixtureDef wheelFixtureDef = new FixtureDef();
wheelFixtureDef.density = fixtureDef.density ;
wheelFixtureDef.friction = 2;
wheelFixtureDef.restitution = .7f;
focus = new Focus(world, fixtureDef, wheelFixtureDef, 50, 14);
wheelFixtureDef.shape.dispose();
fixtureDef.shape.dispose();
Gdx.input.setInputProcessor(new InputMultiplexer(new InputController() {
#Override
public boolean keyDown(int keycode) {
switch(keycode) {
case Input.Keys.ESCAPE:
dispose();
break;
case Input.Keys.R:
camera.zoom = 1;
break;
case Input.Keys.PLUS:
camera.zoom = 10;
break;
case Input.Keys.MINUS:
camera.zoom = 1;
break;
}
return false;
}
#Override
public boolean scrolled(int amount) {
if(amount == -1 && camera.zoom <= MIN_ZOOM) {
camera.zoom = MIN_ZOOM;
} else {
camera.zoom += amount / PIXELS_PER_METER;
}
return false;
}
},focus));
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(TIME_STEP, VELOCITY_ITERATIONS, POSITION_ITERATIONS);
camera.position.set(focus.getChassis().getWorldCenter().x,focus.getChassis().getWorldCenter().y,0);
camera.update();
String x;
WheelJoint wj = (WheelJoint) focus.getChassis().getJointList().get(0).joint;
x = (int)Math.abs(wj.getJointSpeed())+"";
batch.begin();
font.draw(batch, x, 20, 20);
focus.getSpriteChassis().setPosition((Gdx.graphics.getWidth() / 2 - focus.getSpriteChassis().getWidth() / 2) + focus.getOffSetX(), (Gdx.graphics.getHeight() / 2 - focus.getSpriteChassis().getHeight() / 2) + focus.getOffSetY());
focus.getSpriteChassis().setRotation(focus.getChassis().getAngle() * MathUtils.radiansToDegrees);
focus.getSpriteChassis().setScale(1/camera.zoom);
focus.getSpriteChassis().draw(batch);
focus.getSpriteRearWheel().setPosition((Gdx.graphics.getWidth() / 2 - focus.getSpriteChassis().getWidth() / 2) , (Gdx.graphics.getHeight() / 2 - focus.getSpriteChassis().getHeight() / 2) );
focus.getSpriteFrontWheel().setPosition((Gdx.graphics.getWidth() / 2 - focus.getSpriteChassis().getWidth() / 2) , (Gdx.graphics.getHeight() / 2 - focus.getSpriteChassis().getHeight() / 2) );
//focus.getSpriteRearWheel().setPosition((Gdx.graphics.getWidth() / 2 - focus.getSpriteChassis().getWidth() / 2) + focus.getRwOffSet()*PIXELS_PER_METER*(1/camera.zoom), (Gdx.graphics.getHeight() / 2 - focus.getSpriteChassis().getHeight() / 2) + focus.getRwOffSetY()*PIXELS_PER_METER*(1/camera.zoom) );
//focus.getSpriteFrontWheel().setPosition((Gdx.graphics.getWidth() / 2 - focus.getSpriteChassis().getWidth() / 2)+ focus.getFwOffSet()*PIXELS_PER_METER*(1/camera.zoom) , (Gdx.graphics.getHeight() / 2 - focus.getSpriteChassis().getHeight() / 2) + focus.getFwOffSetY()*PIXELS_PER_METER*(1/camera.zoom));
focus.getSpriteRearWheel().setRotation(focus.getRearWheel().getAngle() * MathUtils.radiansToDegrees);
focus.getSpriteFrontWheel().setRotation(focus.getFrontWheel().getAngle() * MathUtils.radiansToDegrees);
focus.getSpriteRearWheel().setScale(1 / camera.zoom);
focus.getSpriteRearWheel().draw(batch);
focus.getSpriteFrontWheel().setScale(1 / camera.zoom);
focus.getSpriteFrontWheel().draw(batch);
batch.end();
debugRenderer.render(world, camera.combined);
}
#Override
public void resize(int width, int height) {
camera.viewportWidth = width / PIXELS_PER_METER;
camera.viewportHeight = height / PIXELS_PER_METER;
}
#Override
public void hide() { dispose(); }
#Override
public void pause() { }
#Override
public void resume() { }
#Override
public void dispose() {
world.dispose();
debugRenderer.dispose();
batch.dispose();
font.dispose();
}
}
Can anyone help me understand? many thanks !!!
Box2D has a speed limit, which is about 2.0 units/timestep.
So if you step 60 times / second, you can move 2 * 60 = 120 units/second.
To increase the maximum speed you can decrease the timestep i.e. increase the number of steps/second.
If you, for example, increase it to 30, you can move up to 2 * 120 = 240 units/second.
Also make sure, that you are using meters as your unit. Box2D has been created with kg, meters and seconds in mind, so you should also use those units.
I tried everything I could, but my libgdx application won't scale down on android 2.2. It displays a full image of 640x480 on a screen of only 480x320. Here's the code I got so far;
private static final int VIRTUAL_WIDTH = 640;
private static final int VIRTUAL_HEIGHT = 480;
private static final float ASPECT_RATIO = (float)VIRTUAL_WIDTH/(float)VIRTUAL_HEIGHT;
public static Texture BMP_BACKGROUND;
public static Rectangle viewport;
public static OrthographicCamera camera;
public static SpriteBatch batch;
public void create()
{
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
BMP_BACKGROUND = new Texture(Gdx.files.internal("data/bmpSpaceBackground.png"));
BMP_BACKGROUND.setFilter(TextureFilter.Nearest, TextureFilter.Nearest);
batch = new SpriteBatch();
camera = new OrthographicCamera(VIRTUAL_WIDTH, VIRTUAL_HEIGHT);
}
#Override
public void dispose()
{
batch.dispose();
BMP_BACKGROUND.dispose();
}
#Override
public void render()
{
camera.update();
camera.apply(Gdx.gl10);
// set viewport
Gdx.gl.glViewport((int) viewport.x, (int) viewport.y,
(int) viewport.width, (int) viewport.height);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
batch.draw(BMP_BACKGROUND, 0, 0);
Game.run();
}
public void resize(int width, int height)
{
float aspectRatio = (float)width/(float)height;
float scale = 1f;
Vector2 crop = new Vector2(0f, 0f);
if(aspectRatio > ASPECT_RATIO)
{
scale = (float)height/(float)VIRTUAL_HEIGHT;
crop.x = (width - VIRTUAL_WIDTH*scale)/2f;
}
else if(aspectRatio < ASPECT_RATIO)
{
scale = (float)width/(float)VIRTUAL_WIDTH;
crop.y = (height - VIRTUAL_HEIGHT*scale)/2f;
}
else
{
scale = (float)width/(float)VIRTUAL_WIDTH;
}
float w = (float)VIRTUAL_WIDTH*scale;
float h = (float)VIRTUAL_HEIGHT*scale;
viewport = new Rectangle((int)crop.x, (int)crop.y, (int)w, (int)h);
}
Anyone can tell me what I'm doing wrong?
Try this
public void resize(int width, int height)
{
cam.viewportHeight = height; //set the viewport
cam.viewportWidth = width;
if (Config.VIRTUAL_VIEW_WIDTH / cam.viewportWidth < Config.VIRTUAL_VIEW_HEIGHT
/ cam.viewportHeight) {
//sett the right zoom direct
cam.zoom = Config.VIRTUAL_VIEW_HEIGHT / cam.viewportHeight;
} else {
//sett the right zoom direct
cam.zoom = Config.VIRTUAL_VIEW_WIDTH / cam.viewportWidth;
}
cam.update();
}
This does work and i can work with the virutal resolution. But dont forget to set the camera of your stage you are using! Else it does have no effect!
stage.setCamera(camera).
if you have done that you can work with the virtual resolution inside of your stage.
regards
Your code is 1:1 from an example online.