I recently got into Slick2D and Java game development and I've come across a "dead end" in my programming skills. I wish to invert the x and y axis (or only x/only y) for the mouse direction, so if the user moves his mouse upwards, the cursor would go downwards, if he moves it to the left, the cursor goes towards the right etc.
After doing some thorough research, it doesn't seem like people wish to do this quite often and I haven't found any relevant information.
I don't think showing my code is necessary since there isn't anything related to what I wish to do in it, but if you need to see it I will be happy to comply.
(Furthermore, another problem came to mind: the cursor would go outside the window and unfocus the program if the user clicks, is there a way to "imprison" the mouse/cursor inside an area in the window? So the user wouldn't be able to leave the window, unless he presses escape to open the pause state etc.)
Since I am still a novice with Slick2D and Java in general, if you could be very specific in your answers by telling me where my code should be modified (init, render, update...) That would be delightful.
If you want to invert a any integer or float you can always do this B = (A *= -1) the B is an inverted/negated version of A.
In case of the mouse it would look something like this.
int RegularMouseX = Mouse.getX();
int InvertedMouseX = (RegularMouseX *= -1);
Asuming you get the new mouse position in the update method like any sane person would do. Recreate or re-set the inverted mouse variable every update after getting the mouse Position.
Related
I'm making a 2D platformer game. I have created a texture for the platform, that is meant to be repeated over and over to fill the entire platform, without going over. My first attempt was to draw all the pixels from the bitmap manually, but this caused the background to flicker through while moving the platform (the movement and drawing threads are seperate, so the movement can run at a specific speed, while the FPS doesn't need to suffer). I found this technique worked better:
// Init
bitmap = new BitmapDrawable(res, Texture.PLATFORM.getBitmap());
bitmap.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
// Drawing loop
int x = getX() + (isStill() ? 0 : (int)MainActivity.offsetX);
int y = getY() + (isStill() ? 0 : (int)MainActivity.offsetY);
bitmap.setBounds(x, y, x + getWidth(), y + getHeight());
bitmap.draw(canvas);
However, the bitmap appears to be staying static while the platform is acting as a "view hole" to see through to the bitmap. The only work around I can think of is to somehow "offset" the static bitmap:
bitmap.offset(x, y);
Obviously, that isn't a function. I couldn't find one that would do what I want when looking through the docs.
To summon things up, the BitmapDrawable is causing the background to not move with the platform, making it look super weird.
Thanks in advance!
Try these tips in your code:(I assumed the game moves forward in the horizontal direction)
The GUY should only move up and down(with the appropriate touch input) and not forward and backward as you want the focus(or camera alternatively) solely on the GUY.I noticed that the WALL was moving up in your video when the GUY moved from initial higher position of the wall to little bit lower position later, rectify this because the GUY should move down(try to implement Gravity effect).
The WALL should only move forward(mostly) and backward(less often I guess).The WALL shouldn't move up and down normally. Do not apply Gravity effect to it. You can create at least 2 BitmapDrawable instance of WALL for a screen. They are going to be reused sequencially(for eg: If the 1st one goes totally outside of the screen, reshow it in the desired position using setBounds() method) and continue same for others the whole game.
The currently BLUE BACKGROUND, if it is a part of a larger map, then it needs to be appropriately offsetted.
One of the obstacles that I can think of at the time of writing this is to move the WALL down until it goes out of the screen which results in the death of the GUY.
At those places, where I have used the word move, you need to use the setBounds(a, b, c, d) method to make necessary position based changes as I didn't find other way to update the position of a BitmapDrawable instance. I think, you need to use game framework like libGdx to get method of luxury like setOffset(x, y) or of similar sort.
Sorry that I could only present you the ideas without specific code as I do not have past experience working in a project like this. Hope, it helps you in anyway possible.
I am making a simple game.
I have 6 buttons and i want to shuffle them each time on different locations.
So i've made a simple method to achieve this.
private void changeButtonPlace(ImageView button) {
Random r = new Random();
int newXloc = r.nextInt(getScreenWidth() - (2 * button.getLayoutParams().width));
int newYloc = r.nextInt(getScreenHeight() - (3 * button.getLayoutParams().height));
button.setX(newXloc);
button.setY(newYloc);
}
It works pretty well, but sometimes the buttons override each other which means that it goes on the almost the same location. I want each button to be on a unique location and don't touch other buttons.
Any idea how i can achieve this?
Thanks in advance!
What you are looking for is collision detection, and my answer will greatly simplified this process. I suggest searching for collision detection algorithms to learn more.
So, for super simple starts, we can compare the position, length, and height of 2 boxes. For my example, I am going to assume the origin of these to boxes are their upper left corner.
if((boxA.xPos + boxA.length ) < boxB.xPos || boxA.xPos > (boxB.xPos + boxB.length))
That will check if the two boxes are touching along the x-axis, and we can change the values for the y-axis as well
if((boxA.yPos + boxA.height ) < boxB.yPos || boxA.yPos > boxB.yPos + boxB.height)
Now, this is not a very efficient way of doing this. There are lots and lots of better ways to simplified this logic, and save on resources. But, it is quick and dirty, and probably good enough for a small application like your simple game involving only 6 buttons.
So, with these two equations, you can either nest them then run your collision code inside, or you can OR them together to one equation like this:
if(((boxA.yPos + boxA.height) < boxB.yPos || boxA.yPos > (boxB.yPos + boxB.height)) || ((boxA.xPos + boxA.length ) < boxB.xPos || boxA.xPos > (boxB.xPos + boxB.length)))
That is a lot to read for one line, and if you just starting out, I would suggest nesting them so you can better see the flow of logic through the equations. But, keep in mind for the future, if you ever need to squeeze those few extra bits of performance, OR them together to one if statement is alright place to start.
One way would be to make a grid and instead of a random location on the screen use a random point on the grid. That way you can check if the current grid location has a button on it already.
If you want them to be more scattered you could add each button to an array and check that the new doesn't touch the other buttons. Loop infinitely creating random locations and another loop to check they don't hit the other buttons in the array. Once a new location is found add the button and break out of the infinite loop.
You should take in account the width of the button , and before setting the location of the button make sure no button intersect with a simple if, if they do just randomize the intersecting buttons, should be easy to programm
Edit :
Lets make it a bit simpler an assume you have 3 buttons an assuming they are located on a 2d axis with these coordinates
A : 1,0
B : 2,0
C : 5,0
button width : X=2 Y=2
As you can see in this example at first glance it seems as though no button intersects with each other yet if you add the width to B you understand that is real location is B [1,3] ,[-1,1] intersects with the real location of C [4,6],[-1,1] assuming the coordinates are the center of the button
first [,] represents X axis second [,] represents Y axis
therefore your check will be something like so:
For each Button x
For each button x
calculate real coordinates of button x and y check intersection
if exists recalculate the coordinates and start the loop over
this solution is a bit expensive when talking about running time but once you get the idea you will be able to find something easier.
I've read a few articles about dead reckoning, but it's still a bit confusing to me.
I'm pretty sure I understand the concept of point-and-click movement, but how would I update keystroke movement between the client and server, when the end-point of the movement is unknown?
How would you estimate where the player is going (server-side) if there is no end-point?
Let's start with dead reckoning. Try to think about it on a straight line where there is no left or right movement.
You are at point A and want to get to point B. You know the distance to point B so you can compute how much acceleration and velocity it will take to get there. Dead Reckoning works the other way. You are at point A and will move at a set speed to get near point B.
In the video game world they use this method all the time. So don't think about it as you're moving to point B you're just moving towards point B in increments because in like a FPS your point B will constantly moving. When in fact its really only moving in increments in the direction of point B.
Once you get moving forward then you can start worrying about left/right and up/down which will follow the same principle just in different directions.
As for implementing this you have 2 options.
One way, you could make this calculation on the client side then send the new position to the server. Then update what everyone else sees on screen.
The other way which I think is better you can make all these calculations on the server side and just receive an update where you ended up. X-Box live makes one of the consoles the host so that machine is running all the software and the external users are just firing events. This is why you'll hear people complain about having an unfair host advantage.
Now let's look at some code. This script comes from the Unity Sdk standard install package.
/// This script moves the character controller forward
/// and sideways based on the arrow keys.
/// It also jumps when pressing space.
/// Make sure to attach a character controller to the same game object.
/// It is recommended that you make only one call to Move or SimpleMove per frame.
var speed : float = 6.0;
var jumpSpeed : float = 8.0;
var gravity : float = 20.0;
private var moveDirection : Vector3 = Vector3.zero;
function Update() {
var controller : CharacterController = GetComponent(CharacterController);
if (controller.isGrounded) {
// We are grounded, so recalculate
// move direction directly from axes
moveDirection = Vector3(Input.GetAxis("Horizontal"), 0,
Input.GetAxis("Vertical"));
moveDirection = transform.TransformDirection(moveDirection);
moveDirection *= speed;
if (Input.GetButton ("Jump")) {
moveDirection.y = jumpSpeed;
}
}
// Apply gravity
moveDirection.y -= gravity * Time.deltaTime;
// Move the controller
controller.Move(moveDirection * Time.deltaTime);
}
So in this example we have speed which is set to a constant. So when moving in a direction we will travel in that Vector at a constant rate with no care about where point B is located.
Jump speed is how fast will we move in the y axis in the positive direction and gravity in the negative direction stopping at point 0.
So, How can you use this? You could build a server script that executes a move action and have a client side controller that passes the direction information to the server.
So lets say on the client side action is key press down, you send a call to the server to move you in the direction selection and the server will keep you moving you in that direction until action key press up or a change in direction from another input.
I hope this helped.
Let's see... I understand you know how to code, but not what, am I right?
You can feed the keystrokes directly to the server and let it do all the work. The server has no need to know where you are heading, it has your coordinates and direction and that's all it will need, unless you have server-handled AI. In the later case, you can do something similar to raycasting in Unity, start checking what is straight ahead and see if it is anything of interest, if so you know the potential destination.
It is safe to constantly send back to the client all his data, so it is always up to date. If you believe this will strain your connection you can do that every 50ms or as often as you believe is safe, and for smooth function estimate everything on the client side too. Make sure the server does all the collision detection and all the mechanics not related to the UI, or else the game will be prone to client-side malfunction or malicious tampering.
If you do have to look at where the player might be going, you can use a few approaches, you could either have a number of virtual cubes in the world which keep track of what is inside them, which will simplify finding what's ahead in terms of resources, or you could check everything there is, which is rather heavy on the machine, but this adds some other complexities too. In the first case do not forget to stop looking once you hit an obstacle.
You can also calculate the angle between the player's direction and other items of importance to check what else might be on his mind.
The question about UDP has already been answered, plus I'm sure Wikipedia has a helpful book on UDP and TCP, I have nothing to add.
The explanation of dead reckoning was also quite satisfactory, I hope I added other angles to the concept.
I hope I helped, if you need any clarifications or any other help feel free to contact me, if I was less than unhelpful then feel free to downvote, I study computer engineering and am creating my second game for PC so maybe I have ran into some problem already and can share the knowledge.
I have made threads in the past about similar questions but because of my lack of detail the answers have not really been related to what I needed so I am going to try explain my question in as much detail as I can and hopefully it will be easier for you to understand what I require.
I watched Bucky's slick game tutorials on youtube and made a 2D Java game, the game is basically a 2D player viewed from above (birds eye view) can move around a 2D map with user key input (up, down, left, right). The map the player moves around is very small so that meant boundaries had to be set so that the player could not walk off of the map, to give you a better idea of how this was done, here is the tutorial for setting up the voundries:
http://www.youtube.com/watch?v=FgGRHId8Fn8
The video will also show you exactly what the game is like.
The problem is, these boundaries only require one axis meaning that if the player is walking down you say something like "if player gets to the coordinate (number) on the X axis change the player movement to the opposite direction so that he can not go any further."
Now this creates a problem for me because this only requires one axis so it easy to set up and understand but if you look on the video, on the map there is a house and I want my player not to be able to walk over that also but this deals with 2 dimensions, I have looked at things like rectangle collisions and have seen things relating to them in the other posts but I get confused because I am new to Java and havent really done much with it at the moment apart from watching Bucky's tutorials.
My code at the moment for my game class has got the following methods: init, render and update. So to sum it up I really just want to set up a way of not letting my player walk through the house, I will mention also (I should have mentioned it in my other threads) as I am very new to Java, could you please take a step by step method of showing me how to set up the collisions, I mean even the basics of things like making the rectangle if required.
If my code is required please tell me and I will post it as soon as possible.
Thank you in advance.
You can set up the board as a 2x2 grid of a class that has has property such as 'isBlocked'. By default the edges of the board would have this property set to true to prevent the character from walking off the edge. When you add other obstacles such as a house or a wall the grid position(s) the object occupies would also have the property set to true. Then when moving a character you just check if the grid position the character moves to has the property set to false to see if it's an allowable move. This also makes it quite trivial to save the level data so you can just load them from disk later on.
Two possible options:
Extend Shape or Rectangle or the relevant Slick objects (they should exist IMO) and just check for intersect()
Look for (x1,y1) and (x2,y2) values such that it starts outside and ends up inside.
Assuming you have intersect() methods:
//Grab the previous position
prevPosX = movingobject.X;
prevPosY = movingobject.Y;
//Update the position
movingobject.update();
//Test for collision
if(movingobject.intersects(targetobj)) {
//If it collided, move it back
movingobject.X = prevPosX;
movingobject.Y = prevPosY;
//And reverse the direction
//(might want to do other stuff - e.g. just stop the object)
movingobject.speed *= -1; //Reverse the speed
}
in this case your update class should also add one more condition to look for the house. let say the cooridnates of house(assuming rectanglular house here for other shape just change x and y values) are (x1,y1)(x1,y2)(x2,y2)(x3,y1) you have to add a condition to make sure
x value is not between x1 and x2 and at the same time y value cannot between y1 and y2.
For those of you who have played Madness Interactive, one of the most frustrating things is when the cursor leaves the game area, and you accidentally click. This causes the game to defocus and your character dies in a matter of seconds. To fix this, I'd like to make a java application that I can run in the background that will hold the cursor inside the screen until I press a key, like ESC or something.
I see two ways of implementing this, but I don't know if either of them are workable.
Make an AWT frame that matches the size of Madness Interactive's render area, and control the cursor using that.
Use some out-of-context operating system calls to keep the cursor in a given area.
Advantage of approach #1: Much easier to implement resizing of the frame so that user can see the shape and position of the enclosed area.
Potential Problems with approach #1: The AWT Frame would likely need to steal focus from the browser window the game is running in, making the whole solution pointless.
My question is, are either of these approaches viable? If not, is there a viable option?
EDIT: I am willing to use another programming language if necessary.
EDIT2: I might develop a browser plugin for this, but I've never done that kind of development before. I'll research it.
If you're still interested in working in Java, here's a possible solution for you.
First, in order to limit the cursor within an area, you could use the Java Robot class.
mouseMove(int x, int y);
Then, you could use AWT's MouseInfo to get the position of the mouse cursor.
PointerInfo mouseInfo = MouseInfo.getPointerInfo();
Point point = mouseInfo.getLocation();
int x = (int) point.getX();
int y = (int) point.getY();
Then, whenever the x and y value of the mouse cursor go beyond a certain point, move them back using the Java Robot class.
If this is for a browser-based game, consider writing a greasemonkey script, which acts as a browser extension that can be filtered to only run on the game's site.
In the simplest case, assume the clickable regions are (0,0) - (300,400), then you can add the following event handler to the page:
$(document).on('click', function(event) {
if (event.pageX > 300 || event.pageY > 400) {
return false;
}
});
You can further refine your script to do the following:
resize the browser to be the perfect size for playing the game
instead of checking the absolute x,y coords of the click, check if it is inside an element of the page that you don't want to receive the click
add custom key bindings to umm.. help you at the game
write a javascript bot that can play the game itself