Tilemap.cs 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. // $Id: foo.cpp 2979 2006-01-10 00:00:04Z sommer $
  2. //
  3. // Cobble - A simple SuperTux level editor
  4. // Copyright (C) 2006 Christoph Sommer <supertux@2006.expires.deltadevelopment.de>
  5. //
  6. // This program is free software; you can redistribute it and/or
  7. // modify it under the terms of the GNU General Public License
  8. // as published by the Free Software Foundation; either version 2
  9. // of the License, or (at your option) any later version.
  10. //
  11. // This program is distributed in the hope that it will be useful,
  12. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. // GNU General Public License for more details.
  15. //
  16. // You should have received a copy of the GNU General Public License
  17. // along with this program; if not, write to the Free Software
  18. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19. // 02111-1307, USA.
  20. using System;
  21. using System.Collections.Generic;
  22. using System.Text;
  23. using Lisp;
  24. namespace Cobble {
  25. public class Tilemap {
  26. public int layer;
  27. public bool solid;
  28. public float speed;
  29. public int width;
  30. public int height;
  31. public List<int> tiles;
  32. public Tilemap(Parser parser) {
  33. int d = parser.Depth;
  34. while (parser.Parse() && parser.Depth >= d) {
  35. if (parser.Depth == d + 1) {
  36. if (parser.Type != Parser.LispType.SYMBOL)
  37. throw new Exception("expected SYMBOL");
  38. string symbol = parser.SymbolValue;
  39. parser.Parse();
  40. switch (symbol) {
  41. case "z-pos":
  42. this.layer = parser.IntegerValue;
  43. break;
  44. case "solid":
  45. this.solid = parser.BoolValue;
  46. break;
  47. case "speed":
  48. this.speed = parser.FloatValue;
  49. break;
  50. case "width":
  51. this.width = parser.IntegerValue;
  52. break;
  53. case "height":
  54. this.height = parser.IntegerValue;
  55. break;
  56. case "tiles":
  57. ParseTiles(parser);
  58. break;
  59. default:
  60. throw new Exception("Unexpected entry in tilemap list: " + parser.SymbolValue);
  61. }
  62. }
  63. }
  64. }
  65. public Tilemap(int layer, bool solid, int width, int height) {
  66. this.layer = layer;
  67. this.solid = solid;
  68. this.speed = 1.0F;
  69. this.width = width;
  70. this.height = height;
  71. this.tiles = new List<int>(width * height);
  72. for (int i = 0; i < width * height; i++) this.tiles.Add(0);
  73. }
  74. public void Write(LispWriter writer) {
  75. writer.StartList("tilemap");
  76. writer.Write("layer", this.layer);
  77. writer.Write("solid", this.solid);
  78. writer.Write("speed", this.speed);
  79. writer.Write("width", this.width);
  80. writer.Write("height", this.height);
  81. writer.Write("tiles", this.tiles);
  82. writer.EndList("tilemap");
  83. }
  84. public override string ToString() {
  85. switch (this.layer)
  86. {
  87. case -100:
  88. return "Background (-100)";
  89. case 0:
  90. return "Interactive (0)";
  91. case 100:
  92. return "Foreground (100)";
  93. default:
  94. return "Layer " + this.layer.ToString();
  95. }
  96. }
  97. private void ParseTiles(Parser parser) {
  98. this.tiles = new List<int>();
  99. if (parser.Type == Parser.LispType.END_LIST) return;
  100. int d = parser.Depth;
  101. do {
  102. if (parser.Type != Parser.LispType.INTEGER) throw new Exception("unexpected lisp data: " + parser.Type);
  103. this.tiles.Add(parser.IntegerValue);
  104. } while (parser.Parse() && parser.Depth >= d);
  105. }
  106. public int getTileAt(int px, int py) {
  107. if (px < 0) return 0;
  108. if (py < 0) return 0;
  109. if (px >= width) return 0;
  110. if (py >= height) return 0;
  111. return tiles[(width * py) + px];
  112. }
  113. public void setTileAt(int px, int py, int id) {
  114. if (px < 0) return;
  115. if (py < 0) return;
  116. if (px >= width) return;
  117. if (py >= height) return;
  118. tiles[(width * py) + px] = id;
  119. }
  120. public void OffsetBy(int offsetX, int offsetY) {
  121. List<int> newTiles = new List<int>();
  122. for (int i = 0; i < width * height; i++) newTiles.Add(0);
  123. for (int ty = 0; ty < height; ty++) {
  124. for (int tx = 0; tx < width; tx++) {
  125. newTiles[(width * ty) + tx] = getTileAt((tx+2*width-offsetX)%width, (ty+2*height-offsetY)%height);
  126. }
  127. }
  128. this.tiles = newTiles;
  129. }
  130. public void ResizeTo(int newWidth, int newHeight) {
  131. List<int> newTiles = new List<int>();
  132. for (int i = 0; i < newWidth * newHeight; i++) newTiles.Add(0);
  133. for (int ty = 0; ty < newHeight; ty++) {
  134. for (int tx = 0; tx < newWidth; tx++) {
  135. newTiles[(newWidth * ty) + tx] = getTileAt(tx, ty);
  136. }
  137. }
  138. this.width = newWidth;
  139. this.height = newHeight;
  140. this.tiles = newTiles;
  141. }
  142. public void Replace(int oldId, int newId) {
  143. for (int ty = 0; ty < height; ty++) {
  144. for (int tx = 0; tx < width; tx++) {
  145. if (getTileAt(tx, ty) == oldId) setTileAt(tx, ty, newId);
  146. }
  147. }
  148. }
  149. }
  150. }