Currently I am working on a game with LWJGL. I have started to implement a main menu screen although I have an issue.
Currently the button is just a Quad rendered as two triangles.
I know I am making a newbie mistake.
Edit: Sorry, I forgot to say the button is not showing anywhere.
Here is the relevant code:
Game:
if(state == GameState.MAIN_MENU){
Graphics.doMainMenuGraphics();
}
Graphics:
public static void doMainMenuGraphics(){
GL11.glClearColor(255, 255, 255, 0);
Setup.updateGraphics(GL_TRIANGLES);
glEnd();
menubutton.draw(); //Type is Button
}
Button:
//Only relevant code
#Override
public void draw() {
if(hover){
GL11.glBegin(GL11.GL_TRIANGLES);
GL11.glColor3ub((byte) 0, (byte) 50, (byte) 205);
GL11.glVertex2f(x-20, y-5);
GL11.glVertex2f(x-20, y+5);
GL11.glVertex2f(x+20, y+5);
GL11.glVertex2f(x-20, y-5);
GL11.glVertex2f(x+20, y-5);
GL11.glVertex2f(x+20, y+5);
GL11.glEnd();
}else{
GL11.glBegin(GL11.GL_TRIANGLES);
GL11.glColor3ub((byte) 150, (byte) 150, (byte) 155);
GL11.glVertex2f(x-20, y-5);
GL11.glVertex2f(x-20, y+5);
GL11.glVertex2f(x+20, y+5);
GL11.glVertex2f(x-20, y-5);
GL11.glVertex2f(x+20, y-5);
GL11.glVertex2f(x+20, y+5);
GL11.glEnd();
}
GL11.glColor3ub((byte) 255, (byte) 255, (byte) 255);
}
#Override
public void update() {
if(Mouse.getX() < x + 20 && Mouse.getX() > x - 20){
if(Mouse.getY() < y + 5 && Mouse.getY() > y - 5){
hover = true;
}
}
}
Thanks in advance, Curlip.
Related
I'm a beginner working with Processing trying to create a moving cloud sketch. They are to appear on mouseClick, and horizontally move across the screen.
void mousePressed() {
int newCloud {
xpos: mouseX;
ypos: mouseY;
}
clouds.push(newCloud);
}
Here is the area I'm unable to fix, trying to work out the mousePressed part.
and here is my full code! It seems a simple fix but I've tried a bunch of ways rewriting it without succsess.
int[] clouds;
int cloudx;
int cloudy;
int xpos, ypos;
void setup() {
size(600, 600);
int cloudx=mouseX;
int cloudy=mouseY;
}
void draw() {
background(100);
for (int i = 0; i < clouds.length; i++) {
int[] currentObj = clouds[i];
cloud(currentObj.xpos, currentObj.ypos, currentObj.size);
currentObj.xpos += 0.5;
currentObj.ypos += random(-0.5, 0.5);
if (clouds[i].xpos > width+20) {
clouds.splice(i, 1);
}
}
}
void makeCloud (int x, int y){
fill(250);
noStroke();
ellipse(x, y, 70, 50);
ellipse(x + 10, y + 10, 70, 50);
ellipse(x - 20, y + 10, 70, 50);
}
void mousePressed() {
int newCloud {
xpos: mouseX;
ypos: mouseY;
}
clouds.push(newCloud);
}
I had tried to make a new function, though the clouds wouldnt show, I also tried calling the makeCloud function though i know I need to be updating within this new function. Overall, I need help with how to write this statement for newCloud in the mousePressed function.
Your code is irreparable for many reasons.
int[] clouds; will create a reference for Array of single integers, not objects,
void makeCloud (int x, int y){...}, will just draw some ellipses,
clouds.splice(i, 1); inside an Array will not work at all,
This is a working reconstruction of Your problem:
ArrayList<Cloud> clouds = new ArrayList<Cloud>();
void setup() {
size(600, 600);
}
void draw() {
background(100);
drawClouds(clouds);
removeExcessClouds(clouds);
}
/**
** Cloud class
**/
class Cloud {
float xPos;
float yPos;
Cloud(float x, float y) {
xPos = x;
yPos = y;
}
void draw() {
fill(250);
noStroke();
ellipse(xPos, yPos, 70, 50);
ellipse(xPos + 10, yPos + 10, 70, 50);
ellipse(xPos - 20, yPos + 10, 70, 50);
}
void positionUpdate(float deltaX) {
xPos += deltaX;
yPos += random(-0.5, 0.5);
}
}
void drawClouds(ArrayList<Cloud> cds) {
float wind = 0.5;
for (Cloud cd : clouds) {
cd.draw();
cd.positionUpdate(wind);
}
}
void removeExcessClouds(ArrayList<Cloud> cds) {
int cdAmount = clouds.size();
for (int i = 0; i<cdAmount; i++) {
if (clouds.get(i).xPos > width+20) {
clouds.remove(i);
cdAmount = clouds.size();
}
}
}
void mousePressed() {
clouds.add(new Cloud(mouseX, mouseY));
println(mouseX + ", " + mouseY + " : " + clouds.size());
}
Note:
global List initiation:
ArrayList clouds = new ArrayList();
List proper iteration:
for (Cloud cd : clouds) { foo(cd); }
draw method inside a Cloud,
passing values when calling methods.
So, now You can iterate over a List of Objects, and call a draw method inside each Cloud.
As said in the other answer, you will need to refactor your code to use objects.
This looks like an atempt at a JS object literal - Java doesn't use them.
int newCloud {
xpos: mouseX;
ypos: mouseY;
}
You need to instance a Class:
Cloud myCloud = new Cloud(0,5); // You create a new variable of the Cloud type and initialize it with a new Cloud object (essentially calling the constructor)
class Cloud{
int posX, posY;
Cloud(int px, int py){ // This is called a constuctor and its the way a new instance is created
this.posX = px;
this.posY = py;
}
}
Than for the array of clouds you need an ArrayList of Clouds:
ArrayList<Cloud> clouds = new ArrayList<Cloud>();
in the mousePressed event you than just add the new cloud to the arraylist:
clouds.add(myCloud);
I begin to animate a blue square in HTML5 inside a canvas tag, I add another red square as enemy; but when I move the blue square, the red one disappear and the blue one turn red. In fact, I want to keep the color of the blue square and I don't want the red one disappear, how can I solve this problem?
var x = 10;
var y = 360;
var xEnnemy = 190;
var yEnnemy = 10;
var v = 4;
var width = 400;
var height = 400;
var can = document.getElementById("can");
var ctx = can.getContext("2d");
ctx.fillStyle = "skyblue";
ctx.fillRect(x, y, 40, 40);
ctx.fillStyle = "red";
ctx.fillRect(xEnnemy, yEnnemy, 20, 20);
window.onkeydown = function direc(e) {
//Move left
if (e.keyCode == 37 && x > 0) {
x -= v;
}
//Move up
if (e.keyCode == 38 && y > 0) {
y -= v;
}
//Move right
if (e.keyCode == 39 && x < (width - 40)) {
x += v;
}
//Move down
if (e.keyCode == 40 && y < (height - 40)) {
y += v;
}
ctx.clearRect(0, 0, width, height);
ctx.fillRect(x, y, 40, 40);
}
function ennemy() {
ctx.fillStyle = "red";
ctx.fillRect(xEnnemy, yEnnemy, 40, 40);
}
#can {
border: 1px solid black;
}
<html>
<body>
<canvas id="can" width="400" height="400"></canvas>
</body>
</html>
Using ctx.clearRect(0, 0, width, height); clears the entire scene so you need to redraw everything.
You probably want to define a drawPlayer function similar to ennemy like:
function drawPlayer(){
ctx.fillStyle = "skyblue";
ctx.fillRect(x, y, 40, 40);
}
Then, after updating the game state you'd call:
ctx.clearRect(0, 0, width, height);
drawPlayer();
ennemy();
This will update the canvas with the new positions and with the appropriate colors.
Look at what you are doing in the: function direc(e) {
ctx.clearRect(0, 0, width, height);
ctx.fillRect(x, y, 40, 40);
That is effectively wiping the canvas and only drawing one rectangle...
Here is what I would do
var player = {x:10, y:100, v: 4}
var enemy = {x:190, y:10};
var can = document.getElementById("can");
var ctx = can.getContext("2d");
window.onkeydown = function direc(e) {
if (e.keyCode == 37 && player.x > 0)
player.x -= player.v; // Move left
if (e.keyCode == 38 && player.y > 0)
player.y -= player.v; // Move up
if (e.keyCode == 39 && player.x < (can.width - 40))
player.x += player.v; // Move right
if (e.keyCode == 40 && player.y < (can.height - 40))
player.y += player.v; // Move down
draw()
}
function draw() {
ctx.clearRect(0, 0, can.width, can.height);
ctx.fillStyle = "skyblue";
ctx.fillRect(player.x, player.y, 40, 40);
ctx.fillStyle = "red";
ctx.fillRect(enemy.x, enemy.y , 20, 20);
}
draw()
#can {
border: 1px solid black;
}
<canvas id="can" width="400" height="160"></canvas>
I consolidated all the drawing in one location function draw() any time we need to draw we can call that, at the moment you only have one event: onkeydown but as your game gets more complex very likely you will have more and they all will require drawing, we just call the same function.
Also I introduced objects player = {x:10, y:100, v: 4} that keep all the properties of the player in one object, that makes the code easier to read
How can I drag a texture (image) without making it jump and centering itself on the mouse cursor (what I have below in my code)?
When I click on the texture, nothing should happen, and when I drag, the mouse cursor should stay in place (relative to the edges of the texture).
Example: https://s31.postimg.org/ojapwbj6j/Untitled_1.jpg
SpriteBatch batch;
Texture texture;
OrthographicCamera camera;
Vector3 spritePosition = new Vector3();
float offsetX, offsetY;
Vector3 input;
#Override
public void create () {
batch = new SpriteBatch();
texture = new Texture("badlogic.jpg");
camera = new OrthographicCamera();
camera.setToOrtho(false);
}
#Override
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(texture, spritePosition.x, spritePosition.y);
batch.end();
if (Gdx.input.justTouched()){
int x1 = Gdx.input.getX();
int y1 = Gdx.input.getY();
input = new Vector3(x1, y1, 0);
camera.unproject(input);
offsetX = x1 - spritePosition.x;
offsetY = y1 - spritePosition.y;
}
if (Gdx.input.isTouched()) {
spritePosition.set(Gdx.input.getX() - offsetX, Gdx.input.getY() - offsetY, 0);
}
}
What you need to do is work out the offset of the mouse position relative to your image, and subtract that, rather than half the width / height as you're doing at the moment.
Here's some very rough pseudocode to show what I mean - You'll need to rewrite as Java...
if Gdx.input.justTouched {
get mouse position from Gdx.input
camera.unproject it into cameraX and cameraY
offsetX = cameraX - imageX
offsetY = cameraY - imageY
}
if Gdx.input.isTouched {
spritePisition.set(Gdx.input.getX() - offsetX, Gdx.input.getY - offsetY)
}
Why are you using camera.unproject?
Try this:
Override
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(texture, spritePosition.x, spritePosition.y);
batch.end();
if (Gdx.input.isTouched()) {
spritePosition.set(Gdx.input.getX() - texture.getWidth() / 2, Gdx.input.getY() + texture.getHeight() / 2, 0);
}
}
I am making a game where there are different objects fall from the upper part of the screen to the lower part of the screen. I am having problems with how can I choose what TextureRegion randomly to be spawned and not to change the already spawned TextureRegions. When I run the game lets say that the electronRegion is spawned first then when the next is spawned and let's say it's an antiprotonRegion the first electronRegion changes to antiprotonRegion that I don't want.
Here is my game class:
public class GameScreenTest implements Screen {
...
#Override
public void render(float delta) {
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.batch.disableBlending();
game.batch.draw(background, 0, 0);
game.batch.enableBlending();
for(Particles particle: particles) {
particlesControl.draw(particle.x, particle.y);
}
game.batch.end();
if(TimeUtils.millis() - lastDropTime > 500) {
particlesControl.spawn();
particlesControl.update();
}
Iterator<Particles> iter = particles.iterator();
while(iter.hasNext()) {
Particles particle = iter.next();
particle.y -= 200 * Gdx.graphics.getDeltaTime();
if(particle.y + particle.height < 0) {
iter.remove();
}
}
}
...
private class Particles {
private int width;
private int height;
private int x;
private int y;
private Particles() {
}
private void spawn() {
Particles particle = new Particles();
particle.x = MathUtils.random(0, 480 - width);
particle.y = 800;
particle.width = width;
particle.height = height;
particles.add(particle);
lastDropTime = TimeUtils.millis();
}
private void update() {
choice = MathUtils.random(1, 4);
switch(choice) {
case 1:
chosen = new TextureRegion(protonRegion);
width = 75;
height = 75;
break;
case 2:
chosen = new TextureRegion(electronRegion);
width = 75 / 2;
height = 75 / 2;
break;
case 3:
chosen = new TextureRegion(antiprotonRegion);
width = 75;
height = 75;
break;
case 4:
chosen = new TextureRegion(antielectronRegion);
width = 75 / 2;
height = 75 / 2;
break;
}
}
private void draw(int x, int y) {
game.batch.draw(chosen, x, y, width, height);
}
}
I want to know why does all the spawned objects change every time a random choice is taken, and of course, how to solve this problem. Thank You.
Tray this:
public class GameScreenTest implements Screen {
final AntimatterBlast game;
private Texture gameObjects;
private TextureRegion electronRegion;
private TextureRegion antielectronRegion;
private TextureRegion protonRegion;
private TextureRegion antiprotonRegion;
//===========================================//
//remove private TextureRegion chosen;
//===========================================//
private TextureRegion background;
private Music gameMusic;
private OrthographicCamera camera;
private Array<Particles> particles;
private Particles particlesControl;
private long lastDropTime;
private int choice;
public GameScreenTest(final AntimatterBlast game) {
this.game = game;
gameObjects = new Texture(Gdx.files.internal("GameObjects.png"));
electronRegion = new TextureRegion(gameObjects, 105, 103, 50, 50);
antielectronRegion = new TextureRegion(gameObjects, 105, 155, 46, 46);
protonRegion = new TextureRegion(gameObjects, 6, 6, 100, 100);
antiprotonRegion = new TextureRegion(gameObjects, 6, 108, 90, 90);
background = new TextureRegion(gameObjects, 0, 204, 480, 800);
gameMusic = Gdx.audio.newMusic(Gdx.files.internal("DST-ElektroHauz.mp3"));
gameMusic.setLooping(true);
camera = new OrthographicCamera();
camera.setToOrtho(false, 480, 800);
particles = new Array<Particles>();
particlesControl = new Particles();
//===========================================//
//choice = MathUtils.random(1, 4); //remove
//chosen = new TextureRegion(protonRegion); //remove
//===========================================//
}
#Override
public void render(float delta) {
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
game.batch.disableBlending();
game.batch.draw(background, 0, 0);
game.batch.enableBlending();
for(Particles particle: particles) {
//===========================================//
particlesControl.draw(particle.chosen, particle.x, particle.y);
//change
//particlesControl.draw(particle.x, particle.y);
//===========================================//
}
game.batch.end();
if(TimeUtils.millis() - lastDropTime > 500) {
//===========================================//
particlesControl.spawn();
//===========================================//
//===========================================//
//remove particlesControl.update();
//===========================================//
}
Iterator<Particles> iter = particles.iterator();
while(iter.hasNext()) {
Particles particle = iter.next();
particle.y -= 200 * Gdx.graphics.getDeltaTime();
if(particle.y + particle.height < 0) {
iter.remove();
}
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
gameMusic.play();
particlesControl.spawn();
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
gameObjects.dispose();
gameMusic.dispose();
}
private class Particles {
//===========================================//
private TextureRegion chosen; //add variable
//===========================================//
private int width;
private int height;
private int x;
private int y;
private Particles() {
}
private void spawn() {
Particles particle = new Particles();
particle.x = MathUtils.random(0, 480 - width);
particle.y = 800;
particle.width = width;
particle.height = height;
//===========================================//
particle.selectTexture();
//===========================================//
lastDropTime = TimeUtils.millis();
//===========================================//
selectTexture(); //add call
//===========================================//
particles.add(particle);
}
//===========================================//
private void selectTexture() { //change name, but is not nesesari
//===========================================//
choice = MathUtils.random(1, 4);
switch(choice) {
case 1:
//===========================================//
//change
//chosen = new TextureRegion(antielectronRegion);
//if you are not going to change or modific TextureRegion
//independet other the textureRegion,
//I think you could use it well.It is just an idea
chosen = protonRegion;
//===========================================//
width = 75;
height = 75;
break;
case 2:
//===========================================//
//change
//chosen = new TextureRegion(antielectronRegion);
//if you are not going to change or modific TextureRegion
//independet other the textureRegion,
//I think you could use it well.It is just an idea
chosen = electronRegion;
//===========================================//
width = 75 / 2;
height = 75 / 2;
break;
case 3:
//===========================================//
//change
//chosen = new TextureRegion(antielectronRegion);
//if you are not going to change or modific TextureRegion
//independet other the textureRegion,
//I think you could use it well.It is just an idea
chosen = antiprotonRegion;
//===========================================//
width = 75;
height = 75;
break;
case 4:
//===========================================//
//change
//chosen = new TextureRegion(antielectronRegion);
//if you are not going to change or modific TextureRegion
//independet other the textureRegion,
//I think you could use it well.It is just an idea
chosen = antielectronRegion;
//===========================================//
width = 75 / 2;
height = 75 / 2;
break;
}
}
//===========================================//
private void draw(TextureRegion chosen, int x, int y) {
game.batch.draw(chosen, x, y, width, height);
//===========================================//
}
}
}
Like I said in the previous comment the texture (chosen) is in the GameScreenTest and you are using it in the inner class so every single instance of the Particles class will share the same texture.
Not error causing but it might help you to organize the code and make it more readable and by all means you are not obligated to make them just take them as suggestions:
Naming conventions
Naming the class Particles make it seem like the class represents more than 1 Particle, but in fact it represents a single Particle maybe name it only Particle.
Separating the game logic
Make the Particle class deal only with its own problems and don't use it to generate other particles and to add it to an outer class.
Using the constructor since it is already there
Give the Particle the texture that it should use and maybe the coordinates.
Drawing "dead" particle
You are drawing first and asking questions later depending on your game it might feel weird since you will always draw a frame while it no longer exists.
Not really sure on this one
But you might be able to reuse the textures regions instead of a creating a new one of the same texture for every single particle
I have this code on a game I am making:
override public function update():void
{
var pressed:Boolean = false;
if (collide("ground", x, y))
{
trace("COLLISION");
}
if (Input.check(Key.LEFT))
{
xSpeed -= power;
pressed = true;
}
if (Input.check(Key.RIGHT))
{
xSpeed += power;
pressed = true;
}
if (collide("ground", x, y + 1))
{
onTheGround = true;
ySpeed = 0;
if (Input.check(Key.UP))
{
ySpeed -= jumpPower;
}
} else {
ySpeed += gravity;
}
if (Math.abs(xSpeed) < 1 && !pressed)
{
xSpeed = 0;
}
xSpeed *= hFriction;
ySpeed *= vFriction;
adjustXPosition();
adjustYPosition();
}
And then I have some tiles on the map generated by this class:
public class Level1 extends Entity
{
private var _tiles:Tilemap;
private var _grid:Grid;
public function Level1()
{
_tiles = new Tilemap(Assets.SPRITE_TILESET, 1920, 1080, 120, 120);
graphic = _tiles;
layer = 1;
_tiles.setRect(0, 0, 1920 / 120, 1080 / 120, 1);
_tiles.setRect(0, 17, 1920 / 120, 1, 0);
_grid = new Grid(1920, 1080, 120, 120, 0, 0);
mask = _grid;
_grid.setRect(0, 17, 1920 / 120, 1, true);
type = "ground";
}
}
But when the player touches on the ground, no collision is detected! And the player just falls through it! What is it that is wrong? I thought "type" was gonna make it work, but I guess I was wrong..
if (collide("ground", x, y))
i think you shouldn't use "x,y" instead of "0,0" because this parameters aren't for position of collision, if i remember right, it is for offset of collision as optional.
so, when you use x,y for this parameters, it may be meaning x+x,y+y as position.
so here,
(collide("ground", x, y + 1))
you should use
(collide("ground", 0, 1))
i'm not sure about that, but you can try this.
Did you give your player a proper HitBox? It looks like your Level1 class is set up properly, but you didn't include the code for your player's hitbox.
You can give your player a basic hitbox like so:
player.setHitbox(64, 64, 0, 0);