views:

66

answers:

2

I'm (still) porting an old Macintosh game to HTML5 and JavaScript. The game is a Tempest clone. (Wikipedia article on Tempest) (Shameless pimp of my project)

While it's certainly possible to implement controls using the keyboard, I'm also wondering if it's possible to make relative mouse movement work in HTML5.

The typical ways that I've seen this implemented (outside of HTML5) is to repeatedly warp the mouse to the screen's center and look for deviations, or to somehow capture raw mouse movement events. As far as I know, but I could be wrong, neither of these methods are possible in HTML5.

The odds are slim, but I figure I shouldn't completely write it off without asking the clever minds of StackOverflow. :)

+1  A: 

I'm pretty sure that the only way to get relative mouse coords in JavaScript (HTML5 specs have no changes to this) is to calculate it from the current mouse position and the previous mouse position - or using onmousemove. As you probably are aware of, this won't work when the cursor can't physically move (eg. is touching window borders)

In the off chance that I'm wrong, you could take a search for WebGL demos. Since there's bound to be a 3D shooter demo, perhaps they have a mouse based control solution you can apply.

Jani Hartikainen
+1  A: 

I don't think you need HTML5 really, but if you have an element and your game board is in the center, you could do something like this:

<html>
<head>
<title>Cursor Position Radius</title>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js" type="text/javascript"></script>
<style type="text/css" media="screen">
#square {
    height: 400px;
    width: 400px;
    background-color: #000;
    margin: auto;
    position: absolute;
    overflow: hidden;
    top: 10px;
    left: 300px;
}
#log {
    height: 100%;
    width: 200px;
    position: absolute;
    top: 0;
    left: 0;
    background-color: #ccc;
    color: #000;
    font-size: small;
    overflow: auto;
}
</style>

<!-- here's the real code, the JavaScript -->

<script type="text/javascript">
$(document).ready(function() {

    var centerTop = a = $('#square').height() / 2;
    var centerLeft = $('#square').width() / 2;
    var squareTop = $('#square').offset().top;
    var squareLeft = $('#square').offset().left;

    // draw a center point
    $('<div />').css({
        width: '1px', height: '1px',
            backgroundColor: '#fff',overflow:'hidden',
            position:'absolute',
            top: centerTop,left: centerLeft
    }).attr('id', 'center').appendTo('#square');
    $('#square').bind('mousemove', function(event) {
        var mouseLeft = (event.pageX - squareLeft);
        var mouseTop = (event.pageY - squareTop);
        var correctTop = (centerTop - mouseTop);
        var correctLeft = (mouseLeft - centerLeft);
        var rawAngle = (180/Math.PI) * Math.atan2(correctTop,correctLeft);
        var intAngle = parseInt(rawAngle, 10);
        var msg = '';
        msg += (mouseTop >= centerTop) ? ' lower ' : ' upper ';
        msg += (mouseLeft >= centerLeft) ? ' right ' : ' left ';
        msg += intAngle;
        $('#log').prepend('<div>' + msg + '</div>');
    });

/* create a dot along a radius for every degree (not necessary for the mousemove) */

    var sensitivity = (2 * Math.PI) / 360;
    var radius = ($('#square').height() / 2) - 10;
    var degrees = 0;
    for (var t = 0; t<= (2 * Math.PI); t+=sensitivity) {
        var x = radius * Math.cos(t) + a;
        var y = radius * Math.sin(t) + a;
        $('<div />').css({
            width: '1px', height: '1px',
                    backgroundColor: '#ccc',overflow:'hidden',
                    position:'absolute',top: x,left: y
        }).attr('id', 'cursor-' + t).appendTo('#square');
    }

});
</script>

<!-- and the body -->

</head>
<body>

<div id="square"></div>
<div id="log"></div>

</body>
</html>

So the idea here is that you would do something with that angle around the center of the game board. If you know that the angle is 90 degrees you know that the game piece is at the far right.

I'm really interested in JavaScript for games, I'll check out your git project. Feel free to contact me and I'll do what I can. I wish I could promise real help, but I'm a newbie myself. There's probably more efficient ways to do the math I do in my sample, I did it mostly as an exercise for myself anyway. Best of luck!


Here's another tack at it, showing an avatar (really just a a bunch of points) that follow the mouse: http://gist.github.com/464974

artlung
That's a rather neat idea. It's not relative movement, but it may be a good Tempest or tube-shooter specific input method. Thanks, I'll have to try this! Biggest difficulty I see is odd levels such as the figure-8.
Shtééf
For the figure 8, I suppose you would need to keep track of which side you are on and use the center of each loop as the center for calculating where you are. Once your avatar crosses over the center, then the angles are ont he other loop. Interesting problem. The control of tempest was a wheel, hard to mimic that with anything but a wheel! :-\
artlung
I was thinking more about relative mouse movement -- you could set a threshold to start movement (maybe 15 pixels?) and then as long as it's moving along your horizontal axis keep moving. Playtesting will reveal how well it works.
artlung