Showing posts with label game. Show all posts
Showing posts with label game. Show all posts

Wednesday, 6 March 2013

Write a Simple Game with LWJGL (LightWeight Java GL)

This post will show a demo on how to write an OpenGL game by using Java.

LWJGL is a framework not only a java tool package but also contains cross-platform complied OpenGL API files. These native clients could work on the following operation systems: Windows, Linux, MacOSX, and Solaris. Despite Java program efficiency issues, LWJGL gets out a possible solution that developers need only deploy the core code and the rests (OpenGL relative) will auto-adjusted by the framework.

Pong is a very famous & simple console game. So I implement it as the ‘Hello World’ project.

image

Initially, let me introduce the basic game logic (although most of you know it XD)

  • 2 Players (one human and one computer), each player controls a bat
  • 1 Ball
  • Control the bat move up and down, try to hit the ball, do not miss it

Sketch:

image

Before we start write code, add LWJGL libraries first.

  1. Download LWJGL jar files
  2. Attach these jar files to out project
  3. Add native GL files to the project. This step is crucial. Select the files which match you current/target operation system
  4. (optional) Add Javadoc
  5. Now it should looks like the image below

image

Great! Ready to work.

============

Firstly, define the entities.

This operation may unnecessary for such small project. But it still helps us to build a well-formed OO program.

image

Two interfaces: Entity & MoveableEntity

Two abstract classes: AbstractEntity & AbstraceMoveableEntity

Code:

package entites;

public interface Entity {
public void draw();
public void update(int delta);
public void setLocation(double x, double y);
public void setX(double x);
public void setY(double y);
public void setWidth(double width);
public void setHeight(double height);
public double getX();
public double getY();
public double getHeight();
public double getWidth();
public boolean intersects(Entity other);

}



package entites;

import java.awt.Rectangle;

public abstract class AbstractEntity implements Entity {

protected double x, y, width, height;
protected Rectangle hitbox = new Rectangle();

public AbstractEntity(double x, double y, double width, double height) {
this.x = x;
this.y = y;
this.width = width;
this.height = height;
}

@Override
public void setLocation(double x, double y) {
this.x = x;
this.y = y;
}

@Override
public void setX(double x) {
this.x = x;
}

@Override
public void setY(double y) {
this.y = y;

}

@Override
public void setWidth(double width) {
this.width = width;

}

@Override
public void setHeight(double height) {
this.height = height;

}

@Override
public double getX() {
return x;
}

@Override
public double getY() {
return y;
}

@Override
public double getHeight() {
return height;
}

@Override
public double getWidth() {
return width;
}

@Override
public boolean intersects(Entity other) {
hitbox.setBounds((int) x, (int) y, (int) width, (int) height);
return hitbox.intersects(other.getX(), other.getY(), other.getWidth(),
other.getHeight());
}

}



package entites;

public interface MoveableEntity extends Entity {
public void setDX(double dx);
public void setDY(double dy);
public double getDX();
public double getDY();
}



package entites;

public abstract class AbstractMoveableEntity extends AbstractEntity implements
MoveableEntity {

protected double dx, dy;

public AbstractMoveableEntity(double x, double y, double width,
double height) {
super(x, y, width, height);
this.dx = 0;
this.dy = 0;
}

@Override
public void update(int delta) {
this.x += delta * dx;
this.y += delta * dy;
}

public void setDX(double dx) {
this.dx = dx;
}

public void setDY(double dy) {
this.dy = dy;
}

public double getDX() {
return dx;
}

public double getDY() {
return dy;
}

}



 


>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>


Time to setup the main body of Pong.



  1. Initialize OpenGL

  2. Initialize all necessary Objects

  3. Make some Objects “move”

  4. Listening users key-press actions

  5. Also, AI should response

  6. Game logic (hit? miss? win? lose?)

  7. Refresh the screen

The codes are very simple. I believe you can understand most of them.
( Because I am lazy ^_^ )


package pong;

import java.util.Random;

import org.lwjgl.*;
import org.lwjgl.input.Keyboard;
import org.lwjgl.opengl.*;
import entites.AbstractMoveableEntity;
import static org.lwjgl.opengl.GL11.*;

public class PongGame {

public static final int WIDTH = 640, HEIGHT = 480;
private boolean isRunning = true;
private long lastFrame;
private Ball ball;
private Bat bat;
private Bat computerBat;

public PongGame() {
setUpDisplay();
setUpOpenGL();
setUpEntities();
setUpTimer();

while (isRunning) {
render();
logic(getDelta());
input();
computer();
Display.update();
Display.sync(60);
if (Display.isCloseRequested()) {
isRunning = false;
}
}

Display.destroy();
}

private void computer() {
if (ball.getX() > 350 && ball.getDX()>0) {
if (ball.getY() + ball.getHeight() / 2 > computerBat.getY()
+ computerBat.getHeight() / 2 + 4
&& computerBat.getY() + computerBat.getHeight() <= HEIGHT) {
computerBat.setDY(0.2);
} else if (ball.getY() + ball.getHeight() / 2 < computerBat.getY()
+ computerBat.getHeight() / 2 - 4
&& computerBat.getY() >= 0) {
computerBat.setDY(-0.2);
} else {
computerBat.setDY(0);
}
}
else{
computerBat.setDY(0);
}
}

private void input() {
if (Keyboard.isKeyDown(Keyboard.KEY_UP) && bat.getY() >= 0) {
bat.setDY(-0.2);
} else if (Keyboard.isKeyDown(Keyboard.KEY_DOWN)
&& bat.getY() <= HEIGHT - bat.getHeight()) {
bat.setDY(0.2);
} else {
bat.setDY(0);
}
}

public long getTime() {
return (Sys.getTime() * 1000) / Sys.getTimerResolution();
}

public int getDelta() {
long time = getTime();
int delta = (int) (time - lastFrame);
lastFrame = time;
return delta;
}

private void logic(int delta) {
ball.update(delta);
computerBat.update(delta);
bat.update(delta);
//ball hit the bat
if (ball.getX() <= bat.getX() + bat.getWidth()
&& ball.getX() >= bat.getX()
&& ball.getY() + ball.getHeight() >= bat.getY()
&& ball.getY() <= bat.getY() + bat.getHeight()) {
ball.setDX(Math.abs(ball.getDX()));
Random ran = new Random();
ball.setDY(ball.getDY() + bat.getDY() / 3
+ (double) (1 - ran.nextInt(2)) / 200);
}
//ball hit the computerBat
if (ball.getX() + 10 >= computerBat.getX()
&& ball.getX() + 10 <= computerBat.getX() + 10
&& ball.getY() + ball.getHeight() >= computerBat.getY()
&& ball.getY() <= computerBat.getY() + computerBat.getHeight()) {
ball.setDX(-Math.abs(ball.getDX()));
}

//top & bot border
if (ball.getY() < 0 || ball.getY() > HEIGHT - ball.getHeight()) {
ball.setDY(-ball.getDY());
}

if (ball.getX() < 0 || ball.getX() > WIDTH - ball.getWidth()) {
//reset game
setUpEntities();
}

//fix DY if DY is too large
if (Math.abs(ball.getDY()) > Math.abs(ball.getDX() * 1.5)) {
ball.setDY(ball.getDY() / 1.5);
}

}

private void render() {
glClear(GL_COLOR_BUFFER_BIT);
ball.draw();
bat.draw();
computerBat.draw();
}

private void setUpTimer() {
lastFrame = getTime();
}

private void setUpEntities() {
bat = new Bat(20, (HEIGHT / 2 - 80 / 2), 10, 80);
computerBat = new Bat(WIDTH - 20 - 10, (HEIGHT / 2 - 80 / 2), 10, 80);
ball = new Ball(WIDTH / 2 - 10 / 2, HEIGHT / 2 - 10 / 2, 10, 10);
ball.setDX(-0.15);
}

private void setUpOpenGL() {
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(0, WIDTH, HEIGHT, 0, 1, -1);
glMatrixMode(GL_MODELVIEW);
}

private void setUpDisplay() {
try {
Display.setDisplayMode(new DisplayMode(WIDTH, HEIGHT));
Display.setTitle("pong");
Display.create();
} catch (LWJGLException e) {
e.printStackTrace();
System.exit(0);
}

}

private static class Bat extends AbstractMoveableEntity {

public Bat(double x, double y, double width, double height) {
super(x, y, width, height);
}

@Override
public void draw() {
//glColor3d(1.0, 1.0, 1.0);
glRectd(x, y, (x + width), (y + height));
}
}

private static class Ball extends AbstractMoveableEntity {

public Ball(double x, double y, double width, double height) {
super(x, y, width, height);
}

@Override
public void draw() {
//glColor3d(1.0, 1.0, 1.0);
glRectd(x, y, x + width, y + height);
}

}

public static void main(String[] args) {
new PongGame();
}
}

Saturday, 16 February 2013

HowTo: Play League of Legends on Linux

Tested on Ubuntu 12.04, League of Legends North America server


http://youtu.be/dfrq26NsFZE




Step 1: Install Wine1.4 and Winetricks
sudo add-apt-repository ppa:ubuntu-wine/ppa
(adds ppa repository of wine)

sudo apt-get update
(updates the database/list)

sudo apt-get install wine1.3
(installs wine1.4)

sudo apt-get install winetricks
(installs winetricks)



Step 2: Install Winetricks Extra Components

winetricks vcrun2005
(installs visual c++ 2005)

winetricks wininet
(installs inet)

winetricks ie6
(installs internet explorer 6)

winetricks d3dx9
(installs directx 9)

winetricks corefonts
(installs several windows fonts)

winetricks adobeair
(installs adobe air)

Step 3: Change Wine1.4 Settings to "Windows 7"

winecfg
(opens wine config)

Then, change the Windows Version Setting to "Windows 7"





Step 4: Move a Previous Install of LoL

You should place the folder (Riot Games) into the following location:
(/home/[USER]/.wine/dosdevices/c:/Program Files/)

Make sure you replace [USER] with the correct name.
ALSO, .wine is sometimes hidden from view, so you may have to find it.





Now that you have completed the above tasks, you will now have to open the LoL Launcher. To do that, you will have to type the following two lines of code into a terminal every time you want to play LoL.
cd "/home/[USER]/.wine/dosdevices/c:/Program Files/Riot Games/League of Legends/RADS/system"
(changes directory to where you have LoL folder installed)

WINEDEBUG=+ntdll wine "rads_user_kernel.exe" run lol_launcher $(ls ../projects/lol_launcher/releases/) LoLLauncher.exe
(runs program under debug mode)

(make sure to replace [USER] with the correct name)

If everything is okay, you could also write a script to do that
(Please ignore "optirun" section in the command because I have special video driver)



Enjoy the game.








Special thanks to:

http://na.leagueoflegends.com/board/showthread.php?t=1946188



Friday, 15 February 2013

Play non-English version WarCraft on an English Windows7

Windows 7 x64 English

One of my friends called me that he has trouble in playing the WarCraft on his system. He bought the laptop in Australia, pre-installed the Windows 7 English language version. However, when he wanted to launch the game, something went wrong:

"WC3 required specific version of Windows"

The source of this issue is that Blizzard implemented a system locale check. If the game locale and the system locale are not equal, WarCraft will load extra language pack.

Luckily, some experts (or hackers?) on the network provided an possible solution: modify the game DLL(Dynamic Link Library).

That "Game.dll" file is normally located in the root folder of the game, you can easily figure it out.

Then, use some Hex editor to edit the file. You could use WinHex, UltraEdit, or
Notepad++ with Hex plugin.

Just copy "HexEditor.dll" to //notepad++//plugins folder ,it will take effect.


Launch notepad++, and open Game.dll (Remember BACKUP the original file!)
then
click the menu bar: plugin -> HEX Editor -> View in HEX


Search string:
3D04080000742A3D04


Modify the 74 to EB, then save the file.


ALL DONE! Enjoy the game.



======================= Other issues ==================================

"I am using gForce 310M, but the game does not run as smooth as it does in the Windows XP"

WC3 runs on DirectX 8.1 while Windows only capacity with DX9 and DX10. Convert operations slow the fps and heavy the CPU's workload.
It is better to switch the game 3D render engine into OpenGL mode to optimize the performance.
Create a new shortcut of the game and add some startup parameter after it:
" -opengl"
Please note that there is an initial space.
Now it should looks like:
"D:\WarCraftIII\" -opengl
Sometimes, activate the shadow effects (under OpenGL) will crash the game.



--------------

"I have a FullHD screen, but the game only supports 1024x768 resolution"

Run "regedit"
Expand the brunch
HKEY_CURRENT_USER\Software\Blizzard Entertainment\Warcraft III\Video

modify the value:
resheight 640 
reswidth 480
to your resolution.