一个简单的页面游戏的尝试

 这个是一个简单页面游戏,没有使用画布 ,纯靠CSS。整体来说还凑合。属于简单、能用的范畴。代码也很少,就是Sprite和GameScene两个类。

页面测试

        function Sprite() {

        }
        Sprite.prototype = {
            config: null,
            init: function (v, s) {
                this.curr = {};
                this.config = v;
                this.scene = s;
                if (this.config.height) {
                } else {
                    var src = this.config.src_list[0];
                    var w = src.width / src.cols;
                    var h = src.height / src.rows;
                    this.config.height = this.config.width / w * h;
                }
            },

            show: function () {
                this.get_div().show();
            },
            hide: function () {
                this.get_div().hide();
            },
            get_div: function () {
                if (this.curr.div)
                    return this.curr.div;
                this.curr.div = $("#div_" + this.config.id);
                return this.curr.div;
            },
            make_html: function (default_pos) {
                var html = [];
                var id = this.config.id;
                var src = this.config.src_list[0];
                var w = src.width / src.cols;
                var h = src.height / src.rows;
                var scal = 100 * src.cols;

                var pos = "";
                var d = 0;
                if (default_pos) {
                    pos = "left:" + default_pos.x + "rem;top:" + default_pos.y + "rem;"
                    d = default_pos.d;
                }
                html.push('<div id="div_' + id + '" class="sprite"  style=" ' + pos + ' background-image: url(' + src.src + ')  ; background-size: ' + scal + '%; background-position:' + this.get_background_position(src, 0, d) + ';    width:' + this.config.width + this.scene.config.size_unit + ';height:' + this.config.height + this.scene.config.size_unit + '"    >');
                html.push('</div>');
                return html.join("");
            },
            get_background_position: function (src, col, row) {
                var w = src.width / src.cols;
                var h = src.height / src.rows;
                var z = this.scene.config.px_per_rem * this.config.width / w;
                var x0 = 0 - w * col * z;
                var y0 = 0 - h * row * z;
                this.src = src;
                this.curr.col = col;
                this.curr.row = row;
                return x0.toString() + "px " + y0.toString() + "px ";
            },
            set_pos: function (x, y, d) {
                var x_p = x - this.config.width / 2;
                var y_p = y - this.config.height;
                this.get_div().css({
                    left: x_p.toString() + this.scene.config.size_unit,
                    top: y_p.toString() + this.scene.config.size_unit
                });
                this.curr.row = d;
            },
            set_pos_center: function (x, y) {
                var x_p = x - this.config.width / 2;
                var y_p = y - this.config.height / 2;
                this.get_div().css({
                    left: x_p.toString() + this.scene.config.size_unit,
                    top: y_p.toString() + this.scene.config.size_unit
                });
            },
            set_status: function (status, d) {
                for (var i = 0; i < this.config.src_list.length; i++) {
                    var src = this.config.src_list[i]
                    if (status == src.group) {
                        var w = src.width / src.cols;
                        var h = src.height / src.rows;
                        this.config.height = this.config.width / w * h;
                        var s = this.get_background_position(src, 0, d);
                        this.get_div().css({
                            "background-image": 'url(' + src.src + ')',
                            "background-size": 100 * src.cols + '%',
                            "height": this.config.height + this.scene.config.size_unit,
                            "background-position": s
                        });
                        return;
                    }
                }
            },
            on_timer: function () {
                var i = this.curr.col + 1;
                if (i >= this.src.cols)
                    i = 0;
                var row = this.curr.row;
                var s = this.get_background_position(this.src, i, row);
                this.get_div().css("background-position", s);
            }
        }

        function GameScene() {

        }
        GameScene.prototype = {
            config: null,
            sprites: null,
            sprite_list: null,
            player: null,
            target: null,
            curr_path: null,
            curr_path_step: 0,
            curr_path_id: null,
            init: function (v) {
                this.sprites = {};
                this.sprite_list = [];

                this.config = v;
                this.show_mask();
                this.init_map();
                this.init_sprite();
                this.hide_mask();
                this.curr_path_id = 0;
                this.sprites["player"].show();
                this.set_player_pos(this.config.width / 2, this.config.height / 2, 0)
                var that = this;
                this.timer = setInterval(function () {
                    that.on_timer();
                }, 140);

                if (this.player.config.pos) {
                    var pos = this.player.config.pos;
                    this.move_player(pos.x, pos.y, 1, function () {
                        that.player.set_status("stand", pos.d);
                    });
                }
                this.target.set_pos_center(pos.x, pos.y);
            },

            on_timer: function () {
                for (var i = 0; i < this.sprite_list.length; i++) {
                    this.sprite_list[i].on_timer();
                }
                //var pos = this.get_player_pos();
                //if (pos) {
                //    var s = pos.x.toFixed(2) + "," + pos.y.toFixed(2);
                //    $("#div_pos").html(s);
                //}

                if (div_succ_visbled) {
                    succ_img_idx = succ_img_idx + 1;
                    if (succ_img_idx > 9) {
                        div_succ_visbled = false;
                        $("#div_succ").hide();
                    } else {
                        $("#img_succ").attr("src", "images/game001/UI/a/60-" + succ_img_idx.toString() + ".png");
                    }  
                }
            },
            init_sprite: function () {
                var html_player = [];
                var html_npc = [];
                for (var i = 0; i < this.config.sprite_list.length; i++) {
                    var rec = this.config.sprite_list[i];
                    var sprite = new Sprite();
                    sprite.init(rec, this);
                    this.sprites[rec.id] = sprite;
                    if (rec.group == "player") {
                        html_player.push(sprite.make_html(sprite.config.pos));
                    }
                    else {
                        html_npc.push(sprite.make_html(sprite.config.pos));
                    }
                    this.sprites[sprite.config.id] = sprite;
                    this.sprite_list.push(sprite);
                }
                $("#" + this.config.div_npc_id).html(html_npc.join(""));
                $("#" + this.config.div_player_id).html(html_player.join(""));
                this.player = this.sprites["player"];
                this.target = this.sprites["target"];

            },
            init_map: function () {
                var w = document.getElementById("div_client").clientWidth;
                var h = document.getElementById("div_client").clientHeight;
                this.config.px_per_rem = w / this.config.width;
                this.config.height = this.config.width / w * h;
                this.config.map_height = this.config.map_width / this.config.map_img_width * this.config.map_img_height;
                var id = "#" + this.config.img_map_id;
                this.map = $(id);
                this.map.css("width", this.config.map_width + this.config.size_unit);
                this.map.css("height", this.config.map_height + this.config.size_unit);
                this.map.css("top", (this.config.height - this.config.map_height) + this.config.size_unit);
                this.map.css("left", (this.config.width - this.config.map_width) + this.config.size_unit);
                this.map.css("background-image", 'url(' + this.config.map_url + ")");
            },
            init_player: function () {
                this.config.player_height = this.config.player_width / this.config.player_img_width * this.config.player_img_height;
                var id = "#" + this.config.img_player_id;
                this.player = $(id);
                this.player.css("width", this.config.player_width + this.config.size_unit);
                this.player.css("height", this.config.player_height + this.config.size_unit);
                this.player.css("top", (this.config.height - this.config.player_height) / 2 + this.config.size_unit);
                this.player.css("left", (this.config.width - this.config.player_width) / 2 + this.config.size_unit);
                this.set_player_status('stop', 0);
            },
            set_player_pos: function (x, y, d) {
                this.player.set_pos(x, y, d);
            },
            get_d: function (x1, y1, x2, y2) {
                var x_inc = Math.abs(x2 - x1);
                var y_inc = Math.abs(y2 - y1);
                var inc = x_inc;
                if (y_inc > inc)
                    inc = y_inc;

                if (y2 < (y1 - inc / 3)) {
                    if (x2 < (x1 - inc / 3))
                        return 2;
                    if (x2 > (x1 + inc / 3))
                        return 3;
                    return 6;

                } else if (y2 > (y1 + inc / 3)) {
                    if (x2 < (x1 - inc / 3))
                        return 1;
                    if (x2 > (x1 + inc / 3))
                        return 0;
                    return 4;

                } else {
                    if (x2 < (x1 - inc / 3))
                        return 5;
                    if (x2 > (x1 + inc / 3))
                        return 7;
                    return 0;
                }

            },
            game_onmousedown: function (x_client, y_client) {
                this.stop_player();
                var left = this.px2rem(this.map.css('left'));
                var top = this.px2rem(this.map.css('top'));
                var x = x_client / this.config.px_per_rem - left;
                var y = y_client / this.config.px_per_rem - top;

                var p = this.get_player_pos();
                var pos1 = { col: Math.round(p.x), row: Math.round(p.y) };
                var pos2 = { col: Math.round(x), row: Math.round(y) };
                var path = this.get_path(pos1, pos2, this.config.map_data);
                //
                //this.move_player(x, y, 0, null);
                //
                this.move_player_path(path, null);
            },
            move_player_path: function (path, call) {
                if (path.length < 2)
                    return;
                this.curr_path = path;
                this.curr_path_id = this.curr_path_id + 1;
                this.curr_path_step = 1;
                if (path.length > 3)
                    this.curr_path_step = 2;
                var p_pos = this.get_player_pos();
                var p_target = this.curr_path[this.curr_path.length - 1];
                this.target.set_pos_center(p_target.col, p_target.row);
                var d = this.get_d(p_pos.x, p_pos.y, p_target.col, p_target.row);
                this.player.set_status("run", d);
                this.step_player_path();
            },
            step_player_path: function () {
                if (this.curr_path_step >= this.curr_path.length) {
                    this.player.set_status("stand", this.player.curr.row);
                    return;
                }
                var idx = this.curr_path_step;
                this.curr_path_step = idx + 1;
                var p_pos = this.get_player_pos();
                var p_target = this.curr_path[idx];
                var d = this.get_d(p_pos.x, p_pos.y, p_target.col, p_target.row);
                if (d != this.player.curr.row) {
                    this.player.set_status("run", d);
                }
                var that = this;
                var x = p_target.col;
                var y = p_target.row;
                var left = this.px2rem(this.map.css('left')) - (x - p_pos.x);
                var top = this.px2rem(this.map.css('top')) - (y - p_pos.y);

                this.map.animate({
                    left: left + this.config.size_unit,
                    top: top + this.config.size_unit
                }, 35, "linear", function () {
                    that.step_player_path();
                });
            },
            stop_player: function () {
                this.map.stop();
                this.curr_path = null;
                this.player.set_status("stand", this.player.curr.row);
                var p_pos = this.get_player_pos();
                this.target.set_pos_center(p_pos.x, p_pos.y);
            },
            move_player: function (x, y, t, call) {
                var that = this;
                var d = 0;
                var p_pos = this.get_player_pos();
                d = this.get_d(p_pos.x, p_pos.y, x, y);

                var left = this.px2rem(this.map.css('left')) - (x - p_pos.x);
                var top = this.px2rem(this.map.css('top')) - (y - p_pos.y);
                if (t == 0) {
                    var l = Math.sqrt(1 + (p_pos.x - x) * (p_pos.x - x) + (p_pos.y - y) * (p_pos.y - y));

                    t = l * 70 + 350;
                }
                this.map.stop();
                this.target.set_pos_center(x, y);
                this.player.set_status("run", d);
                this.map.animate({
                    left: left + this.config.size_unit,
                    top: top + this.config.size_unit
                }, t, function () {
                    that.player.set_status("stand", d);
                    if (call) {
                        call();
                    }
                });
            },
            px2rem: function (v) {
                return parseFloat(v.substr(0, v.length - 2)) / this.config.px_per_rem;
            },
            get_player_pos: function () {
                var left = this.px2rem(this.map.css('left'));
                var top = this.px2rem(this.map.css('top'));

                var left_p = this.px2rem(this.player.get_div().css('left'));
                var top_p = this.px2rem(this.player.get_div().css('top'));
                var x = left_p + this.player.config.width / 2 - left;
                var y = top_p + this.player.config.height - top;
                return { x: x, y: y };
            },
            show_mask: function () {
                $("#" + this.config.div_mask_id).show();
            },
            hide_mask: function () {
                $("#" + this.config.div_mask_id).hide();
            },
            path
            get_v8: function (x_inc, y_inc) {

                if (x_inc == 0) {
                    if (y_inc < 0) {
                        return [[0, -1], [-1, -1], [1, -1], [-1, 0], [1, 0], [-1, 1], [1, 1], [0, 1]];
                    } else if (y_inc > 0) {
                        return [[0, 1], [-1, 1], [1, 1], [-1, 0], [1, 0], [-1, -1], [1, -1], [0, -1]];
                    }
                }
                if (y_inc == 0) {
                    if (x_inc < 0) {
                        return [[-1, 0], [-1, -1], [-1, 1], [0, -1], [0, 1], [1, -1], [1, 1], [1, 0]];
                    } else if (x_inc > 0) {
                        return [[1, 0], [1, -1], [1, 1], [0, -1], [0, 1], [-1, -1], [-1, 1], [-1, 0]];
                    }
                }

                if ((x_inc == 1) && (y_inc == 1)) {
                    return [[1, 1], [1, 0], [0, 1], [1, -1], [-1, 1], [0, -1], [-1, 0], [-1, -1]];
                }
                if ((x_inc == -1) && (y_inc == -1)) {
                    return [[-1, -1], [-1, 0], [0, -1], [-1, 1], [1, -1], [0, 1], [1, 0], [1, 1]];
                }
                if ((x_inc == 1) && (y_inc == -1)) {
                    return [[1, -1], [0, -1], [1, 0], [-1, -1], [1, 1], [-1, 0], [0, 1], [-1, 1]];
                }
                if ((x_inc == -1) && (y_inc == 1)) {
                    return [[-1, 1], [0, 1], [-1, 0], [1, 1], [-1, -1], [1, 0], [0, -1], [1, -1]];
                }
            },
            is_line_path: function (path, i1, i2, map_data) {
                if (path[i1].col == path[i2].col) {
                    for (var i = i1; i <= i2; i++) {
                        if (map_data.data[path[i].row][path[i1].col] < 1)
                            return false;
                    }
                    return true;
                }

                if (path[i1].row == path[i2].row) {
                    for (var i = i1; i <= i2; i++) {
                        if (map_data.data[path[i1].row][path[i].col] < 1)
                            return false;
                    }
                    return true;
                }
                return false;
            },
            smooth_path: function (path, map_data) {
                for (var k = path.length - 1; k > 0; k--) {
                    var x2 = path[k].col;
                    var y2 = path[k].row;

                    var i_line = -1;
                    for (var i = k - 1; i >= 0; i--) {
                        if ((path[i].col == x2) || (path[i].row == y2)) {
                            if (this.is_line_path(path, i, k, map_data)) {
                                i_line = i;
                            }
                        }
                    }
                    if (i_line >= 0) {
                        if (path[i_line].col == x2) {
                            for (var i = i_line; i <= k; i++) {
                                path[i].col = x2;
                            }
                        }
                        if (path[i_line].row == y2) {
                            for (var i = i_line; i <= k; i++) {
                                path[i].row = y2;
                            }
                        }
                    }
                }
                return path;
            },
            get_path: function (pos1, pos2, map_data) {
                var pos_from = pos1;
                var pos_to = this.get_pos_canto(pos2, map_data);

                var rows = map_data.rows;
                var cols = map_data.cols;
                if (map_data.pt) {
                } else {
                    map_data.pt = [];
                    for (var row = 0; row < rows; row++) {
                        var p = [];
                        for (var col = 0; col < cols; col++) {
                            p.push([0, 0]);
                        }
                        map_data.pt.push(p);
                    }
                }
                for (var row = 0; row < rows; row++) {
                    for (var col = 0; col < cols; col++) {
                        if (map_data.data[row][col] >= 1) {
                            map_data.data[row][col] = 1;
                        }
                    }
                }

                var v8 = [[-1, -1], [-1, 0], [-1, 1], [0, 1], [1, 1], [1, 0], [1, -1], [0, -1]];
                var v = v8;
                var pt = [];
                var x_p;
                var y_p;
                var x;
                var y;
                var x_inc;
                var y_inc;

                var xy;
                var is_end = false;
                var pt_tmp = [];
                pt.push(pos_from);
                var path = [];

                map_data.data[pos_from.row][pos_from.col] = 2;
                map_data.pt[pos_from.row][pos_from.col] = [0, 0];
                var maxd = Math.sqrt(map_data.cols * map_data.cols + map_data.rows * map_data.rows);
                for (var d = 3; d < maxd * 8; d++) {
                    pt_tmp = [];
                    for (var i = 0; i < pt.length; i++) {
                        var x_p = pt[i].col;
                        var y_p = pt[i].row;
                        if (x_p <= 0)
                            continue;
                        if (x_p >= cols)
                            continue;
                        if (y_p <= 0)
                            continue;
                        if (y_p >= rows)
                            continue;
                        if (d > 3) {
                            xy = map_data.pt[y_p][x_p];
                            x_inc = x_p - xy[0];
                            y_inc = y_p - xy[1];
                            v = this.get_v8(x_inc, y_inc);
                        }

                        for (k = 0; k < v.length; k++) {
                            x = x_p + v[k][0];
                            y = y_p + v[k][1];

                            if ((map_data.data[y][x] == 1)) {
                                if (map_data.data[y][x] == 1) {
                                    pt_tmp.push({ col: x, row: y });
                                }
                                map_data.data[y][x] = d;
                                map_data.pt[y][x][0] = x_p
                                map_data.pt[y][x][1] = y_p;

                                if ((x == pos_to.col) && (y == pos_to.row)) {
                                    var tmp = [];
                                    for (var m = 0; m < d; m++) {
                                        xy = map_data.pt[y][x];
                                        x = xy[0];
                                        y = xy[1];
                                        if ((x > 0) && (y > 0)) {
                                            tmp.push({ col: x, row: y });
                                        }
                                        else {
                                            break;
                                        }
                                    }
                                    path.push(pos_from);
                                    for (var m = tmp.length - 1; m >= 0; m--) {
                                        path.push(tmp[m]);
                                    }
                                    path.push(pos_to);
                                    is_end = true;
                                    break;
                                }
                            }
                        }
                        if (is_end) {
                            break;
                        }
                    }
                    if (is_end) {
                        break;
                    }
                    pt = pt_tmp;
                }

                return this.smooth_path(path, map_data);
            },
            get_pos_canto: function (pos, map_data) {
                if (map_data.data[pos.row][pos.col] >= 1) {
                    return pos;
                }
                var x1 = 0;
                var x2 = 0;
                var y1 = 0;
                var y2 = 0;
                var maxd = Math.sqrt(map_data.cols * map_data.cols + map_data.rows * map_data.rows);
                for (var d = 1; d < maxd; d++) {
                    x1 = pos.col - d;
                    x2 = pos.col + d;
                    y1 = pos.row - d;
                    y2 = pos.row + d;

                    if (x1 < 0) x1 = 0;
                    if (x2 >= map_data.cols) x2 = map_data.cols - 1;

                    if (y1 < 0) y1 = 0;
                    if (y2 >= map_data.rows) y2 = map_data.rows - 1;

                    for (var x = x1; x <= x2; x++) {
                        if (map_data.data[y1][x] >= 1)
                            return { col: x, row: y1 }
                        if (map_data.data[y2][x] >= 1)
                            return { col: x, row: y2 }
                    }

                    for (var y = y1; y <= y2; y++) {
                        if (map_data.data[y][x1] >= 1)
                            return { col: x1, row: y }
                        if (map_data.data[y][x2] >= 1)
                            return { col: x2, row: y }
                    }
                }
                return null;
            }
        }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

月巴月巴白勺合鸟月半

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值