Board game in javascript, sync questions card - javascript

I'm developing a board game in javascript and I'm almost solved all conditionals and iterations but I still have one problem: it's a game in which you roll the dice and then your pawn moves, and when your pawn reaches certain place on the board, it's supposed to show up a card with questions.
That card is actually a html div, and I just hide and show it by using a .css file.
The thing is, it's "firing" just after I roll the dice, and I can't figure out how to syncronize it with the pawn movements, in order to make it show up when the pawn actually reaches that board section.
The pawn is just an image, and I'm "calling" it using jQuery like this: $("#bluePawn") and then I use an animate function in javascript to make it "move" over the board.
That function receives 4 parameters, which are: the DOM object to move (the pawn as I've referred to before), the pawn's current position on the board, how many spaces to move, and a true/false flag.
I hope this can be more illustrative if I show you the piece of code that issues the movement.
The places where the pawns can be placed and over which they can move, are "marked" on the board with pixel coordinates, included in an associative array
I tried to include an example code but wasn't able to indent it properly.

If you know how long it will take the guy to move you can use setTimeout() to wait the proper length before triggering the card (or a jQuery animate delay.
If you don't know the exact time it will take you should look into callback functions. Trigger the function to show the card (by removing or hiding a css class) AFTER you move the pawns.
This is a generic answer to a generic question without code :)

Related

Using OOP to reduce code and make it reusable

I am creating an application and I have a question about the way in which I go about making it.
You will be able to choose a number which determines the passage of time in minutes for two identical circles. (Separate buttons are created for incrementing and decrementing time for each circle)
As the time passes, the first circle fills up until the countdown for the first circle reaches 0 minutes.
Now a second identical circle will start the countdown and to fill up also based on the initial time you had given to it.
I have linked all the appropriate DOM elements(the circle, the buttons for incrementing/decrementing time) to the functions and event handlers written for the first circle and it runs perfectly. The second circle is essentially the exact same thing, except that it has a different button element for it's events and of course it is a different circle.
If I copy and paste all my code and just change the variables and function names associated with circle 1 to new ones for circle 2 it would work perfectly. That seems very repetitive and I'm sure there is a better way to go about this.
What comes to my mind is OOP. So instead of saying circle1 OR circle2 should fill up when I press this button, I can just say THIS circle fills up, when I press THIS button associated with each circle. Am I right in my thinking ? Is OOP the answer to my question here?
If you can get it to work with code duplication, that's a great start. What you have to do then is called refactoring:
Look for parts of the code which are exactly repeated, and if possible extract them into one function.
Then look for the parts of the code where you are doing things like var1 and var2, and think about ways to abstract that repetition in either a loop over an array, a generator function, or OOP class & instance patterns.
As you go along you will notice that your code will be functionally the same, but much easier to reason about and read.
Also don't be afraid of re-starting from a blank file!

Best/easiest way to make a 2D Chess board using Javascript/HTML5?

I am building a web based chess game in Javascript. I'm using the HTML5 canvas to display the board by drawing rectangles.
I am trying to implement the move logic. So when a chess piece is clicked, and then they click on an empty block, I want to move it. However, it is quite tedious using the canvas. I need to do the following:
Update my 2D grid of objects to reflect the change, I set the current
square to undefined and set the new square to the object being moved
clearRect(..) which I still haven't got to work
Redraw the image at the new position
Is there a better way?
Also, how do I deal with the 'double click'. I currently using a boolean that holds if the piece was pressed, and if it was and they click on an empty square I call the move function. Are there any other ways of doing this? Additionally, are there any tools for making it seem like the chess piece is being dragged?
I appreciate any help. Thanks guys.
Over the years I've written a lot of chessboards for HTML. In the end the simplest approach I think is:
Keep an array (either 1d or 2d, both have pros and cons) with just piece names (e.g. "wp"=white pawn, "bn"=black night, "--" empty). Nothing to be gained with an OO-approach or even a generic piece object.
Use one single canvas for the board, drawing the pieces on them with drawImage.
Write a function that just draws everything and call it when needed (don't bother erasing/drawing single pieces).
For piece dragging empty the square and create a separate dragged div containing just the dragged piece (redrawing the full board during drag can be slow for low-end mobile devices).
For dragging attach move and up handlers to the document and not to the canvas, so that you won't miss up events when the mouse is outside of the browser window.
Start dragging on mousedown and attach events for mousemove and mouseup. This will work both on computers and on mobile phones without having to handle specific cases. Always call preventDefault and stopPropagation.
Make full-page view with no overflow and handle resize yourself (you'll need to add some mobile-specific metas to stop phones messing up with the page).
HTML can really do impressive things with just 2d canvas, as an example see this 2d/3d chessboard. One single file less than 300k (200k zipped).
Easiest you say?
Using chessboard.js has to be the easiest way and it is 2D.
HTML
<div id="board1" style="width: 400px"></div>
JavaScript
var board1 = ChessBoard('board1', 'start');
It has very good documentation and tons of different examples (customization) and can be downloaded here.
Learning by coding -- Good for you!
Here are a few tips to get you started:
A reusable structure for your game:
Create a JS object for each of your chess pieces and save those piece-objects in an array.
// an example piece object
var blackKing={
player:'black',
pieceType:'king',
image:blackKingImageObject,
currentSquare:['E','1'],
isCaptured: false,
// etc...
}
// a pieces-array
var pieces=[];
pieces.push(blackKing);
Create a function that does all of these things:
clearRect the entire canvas,
redraw the chess board,
use the piece-array to redraw all the pieces onto the chessboard.
About click vs double-click vs dragging:
Yes, that's troublesome and requires special handling.
Many coders handle it this way:
Listen for mousedown and save that timestamp and initial mouse position.
If a mouseup plus another mousedown occurs quickly it's a double-click.
If a mousemove of more than a few pixels occurs then it's the start of a drag.
Otherwise, it's a single-click.

HTML5 Canvas game has bug where first puzzle piece changes to a different piece when clicked on?

I think I just need a fresh set of eyes on this game I'm working on.
It's a sliding image puzzle (where you split an image into pieces and display them back in a random order, I then remove a single piece of the puzzle and the user has to click on each puzzle piece to move it around and thus put the image back together)
The full code is here: https://github.com/Integralist/HTML5-Image-Slider-Game
The bug I'm having is on the first puzzle piece you move, if you click it again - when it moves back to the position it just came from - the puzzle piece changes to a different piece (in one instance I noticed that it was changing to the puzzle piece that is removed to initiate the game, but that might just be coincidence).
At first I thought the issue was with the setInterval method which is asynchronous (I was thinking that because I'm inside a loop maybe the reference loop iteration was getting messed up, but I'm now passing in the relevant iteration into the setInterval and the issue still occurs so it can't be that).
UPDATE:
I still think the problem is something to do with the setInterval. The main issue is when we start drawing the image onto the canvas the original x/y co-ordinates obviously have changed from what we expect them to be. I've noticed that the object which holds the co-ordinates for the puzzle piece we want to move is incorrect when we click on the same puzzle piece to move it back into the position it was just in. I noticed the drawnOnCanvasX/Y properties are different to what they should be, and that they now match the x/y co-ordinates of the empty_space variable? The fact that this doesn't happen all the time makes me think that the setInterval is not passing through the correct object from the loop into the function that executes on the interval?
Any help appreciated.
The problem was because I hadn't removed a particular item from the randomised Array.
For the game to work I needed to remove 1 puzzle piece, this allows the other pieces to have a space they can be moved into. Problem was that I had clearRect the piece I wanted but not actually removed it from the Array. So when I was looping through to find an item in the Array that had those exact X/Y co-ordinates it was finding the puzzle piece item that should have been removed (and because the piece that is removed is chosen randomly that's why sometimes that piece would be found via the loop first, and other times the correct piece would be found).
Christ that was painful.

How to dynamically load in page elements (i.e. images) with an animation?

I have a 2-row, 3-column grid of large squares that I'm going to place thumbnail links inside of for categorized navigation. I will worry about elements within the squares later, however, as this question pertains to the actual squares themselves.
First, I want to preload all elements and display them at once. This portion doe not require an animation effect. They can just pop in like normal.
Second, I want this grid of squares to come in. The rest of the page and the squares can come in simultaneously since they will be loaded together. This portion does, however, require an animation effect; I want the squares and their respective children elements to zoom in from nothing.
See the "zoom" effect here.
Third, I'd like to load/animate in the squares in a sequential order, from first to last, each one coming in individually (or slightly overlapping). I'm sure we're just talking parameters now.
Well, that's it. I know this a tall order, but I'm pretty new to jQuery so hopefully someone can help with at least some of it!
I created a plugin todo something similar to this. Have a look at it here: https://github.com/navgarcha/jquery-slotload
You could use the onComplete option to move loaded items before the first .loading image so they appear to load in sequence.
As you require a zoom effect rather than a slot machine like effect you can prob replace the animate code todo the zoom.
Feel free to tear apart the code to suit you.

trouble accessing objects inside of 3d cube

my link: http://dl.dropbox.com/u/7727742/playlistsite6/index5.html
I have a 3d cube using a variation of zachstronaut's demo
(link: http://www.zachstronaut.com/lab/galaxy-box/ ). It uses javascript, translate3d, scale3d, etc...
I've tried assigning different z-index values in the css file, but with no luck. I can access the objects outside the cube(you can see this with the hover effect), but not the objects inside the cube. I have a hunch it is because it's not doing a z-sort type of function like pre3d.js. I was wondering if anyone could offer some insight into where I should look for a solution.
Object coordinates are generated randomly, so you may have to refresh once or twice to get some objects that are inside the cube.
Thanks!
EDIT:
Only tested in safari and chrome dev
Webkit ignores z-indexes on anything that has translate3d defined, as it logically should. z-index is meant for a 2D world, it's like taking a bunch of paper and saying "this one is on top" -- you still have a flat surface. Unfortunately, if you want to be able to select one of the "stars" inside of your box, you're all but out of luck since you're using HTML nodes.
The normal way of doing this is using a click-map -- basically every object gets rendered twice. Once normally and once in a single color with no shading, etc. The 2nd rendering is never shown and is simply used to tell what the user clicked on. You get the color where they clicked and that color maps to a specific object. If you were using canvas, you would do it that way and just change the rendering order on the 2nd render.
Since you're using HTML nodes, you can't do that. You have a couple of options:
You can calculate which star is under the mouse on mouse-move based on viewport rotation and x/y/z position of the star
you can attempt the above method by overlaying an identical rendering without the cube and where the stars have a 0% opacity. Each star in your new rendering would map to a star in your existing one, and you'd have easy mouse-over detection.
Post the results! :)
First of all, I'm glad you found my demo interesting!
You're not going to have much luck trying to do a hover or capture a click event on objects inside of a 3D CSS3 cube for the exact same reason you wouldn't have much luck capturing a hover or click events on a div underneath another div... in HTML all the DOM events go to the top most DOM node. If one div overlaps another div, you can't click the one that is underneath. Everything inside the 3D cube is "underneath" another DOM node.
Things are further complicated because you're taking objects in 3D space and asking a user to interact with them on a 2D plane (the browser window) using a 2D input device (the mouse).
You could hide the faces of the cube so that they wouldn't block the user's clicks. You could do something like cwolves suggested.
Sorry I couldn't be more help... HTML kind of fails us a bit here. Welcome to the bleeding edge!

Categories