⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 staker.m

📁 MATLAB实现的3D炮兵小游戏
💻 M
📖 第 1 页 / 共 5 页
字号:
              updateMainFcn();
              set(hMain,'Visible','on');
            end
            drawnow;

          case 'FONT_NAME',

            value = get(source,'String');
            set(hFont,'FontName',value);
            newPreferences.fontName = value;
            drawnow;

          case 'FONT_SIZE',

            value = round(str2double(get(source,'String')));
            if (isfinite(value) && (value > 0)),
              set(source,'String',num2str(value));
              set(hFont,'FontSize',value);
              newPreferences.fontSize = value;
              drawnow;
            else
              set(source,'String',num2str(newPreferences.fontSize));
              bomb_error(hModal,'invalidValue','font size');
            end

          case 'HELP',

            display_help(hModal);

          case 'NUMERIC',

            value = str2double(get(source,'String'));
            fieldData = get(source,'UserData');
            fieldName = fieldData{1};
            if isnan(value),
              set(source,'String',...
                  num2str(newPreferences.(fieldName),'%0.4f'));
              switch fieldName,
                case 'azimuthGain',
                  bomb_error(hModal,'invalidValue','azimuth gain');
                case 'elevationGain',
                  bomb_error(hModal,'invalidValue','elevation gain');
                case 'rotationGain',
                  bomb_error(hModal,'invalidValue','rotation gain');
                case 'zoomGain',
                  bomb_error(hModal,'invalidValue','zoom gain');
                case 'trajectoryStep',
                  bomb_error(hModal,'invalidValue','trajectory step');
                case 'blastStep',
                  bomb_error(hModal,'invalidValue','blast step');
              end
            else
              value = max(min(value,fieldData{3}),fieldData{2});
              set(source,'String',num2str(value,'%0.4f'));
              newPreferences.(fieldName) = value;
              drawnow;
            end

        end

      end

    end

  end

  %------------------------------------------------------------------------
  function generate_terrain
  %
  %   Generates a game terrain.
  %
  %------------------------------------------------------------------------

    if (isempty(mapX) || isempty(mapY)),
      [mapX,mapY] = meshgrid(MAP_LIMIT.*linspace(-1,1,N_MAP));
    end
    if isempty(mapZ),

      % Initialize terrain and environment variables:

      if (locationIndex == 2),
        locationIndex = round(rand*(length(LOCATION_LIST)-1))+1;
      else
        locationIndex = locationIndex-2;
      end
      mapGenerationState = rand('twister');
      switch LOCATION_LIST{locationIndex},

        case 'Highlands',

          scale = [2000 4000 400]; % Height, expanse, and steepness, in ft
          mapFill = 50*(MAP_LIMIT/(16000*N_MAP))^2;
          index = find(rand(N_MAP) < mapFill); % Obstacle positions
          nSolids = length(index);
          solidObstacles = [index ones(nSolids,1)*scale];
          nGhosts = 0;
          ghostObstacles = [];
          mapFilter = [];
          mapNoise = 200; % ft
          waterLevel = 1000; % ft
          horizonFill = 0.07;
          edgeColor = [0.45 0.45 0.5; 0.5 0.54 0.48];
          locationValue = 1.5; % dollars per billion cubic ft
          windSpeed = 30*normrand(1,-1,5)+30; % 0-180 mph
          if useLocalTime,
            timeOfDay = clock;
            timeOfDay = timeOfDay(4:6);
          else
            timeOfDay = round([23 59 59].*rand(1,3));
          end

      end
      windTheta = 2*pi*rand;
      windVector = windSpeed.*[cos(windTheta) -sin(windTheta) 0];

      % Generate terrain mesh:

      mapZ = zeros(N_MAP);
      for i = 1:nSolids,
        index = solidObstacles(i,1);
        temp = solidObstacles(i,2:4);
        distance = sqrt((mapX-mapX(index)).^2+(mapY-mapY(index)).^2);
        mapZ = mapZ+temp(1)./(1+exp((distance-temp(2))./temp(3)));
      end
      for i = 1:nGhosts,
        index = ghostObstacles(i,1);
        temp = ghostObstacles(i,2:4);
        distance = sqrt((mapX-mapX(index)).^2+(mapY-mapY(index)).^2);
        mapZ = max(mapZ,temp(1)./(1+exp((distance-temp(2))./temp(3))));
      end
      if (~isempty(mapFilter)),
        mapZ = imfilter(mapZ,mapFilter,'replicate');
      end
      mapZ = mapZ+mapNoise.*rand(N_MAP);
      if any(mapZ(:) > (MAX_HEIGHT+waterLevel)),
        mapZ = mapZ.*((MAX_HEIGHT+waterLevel)/max(mapZ(:)));
      end
      if (waterLevel > 0),
        isWater = true;
        mapZ = mapZ-waterLevel;
      end
      mapZ(mapZ < MIN_HEIGHT) = MIN_HEIGHT;

      % Generate horizon:

      nHorizon = ceil(2*pi*HORIZON_LIMIT/MAP_DELTA);
      horizonZ = zeros(1,nHorizon);
      index = find(rand(1,nHorizon) < horizonFill);
      for i = 1:length(index),
        distance = MAP_DELTA.*abs((1:nHorizon)-index(i));
        horizonZ = horizonZ+...
                   scale(1)./(1+exp((distance-scale(2))./scale(3)));
      end
      if (waterLevel > 0),
        horizonZ = horizonZ-waterLevel;
      end
      horizonZ(horizonZ < 0) = 0;
      temp = max(mapZ(:));
      if any(horizonZ > temp),
        horizonZ = horizonZ.*temp./max(horizonZ);
      end
      index = [1:10 (nHorizon-9):nHorizon];
      temp = [linspace(0.5,1,10) linspace(1,0.5,10)];
      horizonZ(index) = temp.*horizonZ(index)+...
                        (1-temp).*fliplr(horizonZ(index));

      % Generate terrain texture map:

      delta = (N_MAP-1)/(2*N_IMAGE);
      index = (1+delta):(2*delta):(N_MAP-delta);
      mapHeight = interp2(mapZ,index,index.');
      if (waterLevel > 0),
        waterLevel = 0;
        nearWater = (imfilter(double(mapHeight < 0),fspecial('disk',10),...
                              'replicate') > 0);
      else
        mapHeight = mapHeight-waterLevel;
      end
      [mapGradientX,mapGradientY] = gradient(mapZ,MAP_DELTA);
      mapGradient = sqrt(mapGradientX.^2+mapGradientY.^2);
      notSteep = (interp2(mapGradient,index,index.') <= SLOPE_LIMIT);
      switch LOCATION_LIST{locationIndex},

        case 'Highlands',

          terrainFile = fullfile(TEXTURE_PATH,'dirt.jpg');
          mapC = double(reshape(imread(terrainFile),N_PIXELS,3));
          index = ~notSteep;
          add_terrain('stone',3);
          index = (mapHeight > SNOW_LINE);
          add_terrain('snow',10);
          tempIndex = notSteep & (mapHeight < 50);
          index = tempIndex & (~nearWater);
          add_terrain('silt',3);
          index = tempIndex & nearWater;
          add_terrain('beach',3);
          tempIndex = notSteep & (mapHeight > 50) & ...
                      (mapHeight < TREE_LINE);
          index = tempIndex;
          index(index) = (rand(sum(index(:)),1) > 0.996);
          index = (imfilter(double(index),fspecial('disk',20),...
                            'replicate') > 0.001) & tempIndex;
          add_terrain('grass',5);
          index = tempIndex;
          index(index) = (rand(sum(index(:)),1) > 0.999);
          index = (imfilter(double(index),fspecial('disk',20),...
                            'replicate') > 0.001) & tempIndex;
          add_terrain('forest',3);

      end
      mapC = reshape(uint8(mapC),N_IMAGE,N_IMAGE,3);

      % Initialize staker positions and settings:

      mapIndex = [2 floor((N_MAP-1)/2) ceil((N_MAP+1)/2)+1 N_MAP-1;...
                  ceil((N_MAP+1)/2)+1 N_MAP-1 2 floor((N_MAP-1)/2);...
                  2 floor((N_MAP-1)/2) 2 floor((N_MAP-1)/2);...
                  ceil((N_MAP+1)/2)+1 N_MAP-1 ceil((N_MAP+1)/2)+1 N_MAP-1];
      muX = 0.625.*MAP_LIMIT.*[1 -1 -1 1];
      muY = 0.625.*MAP_LIMIT.*[-1 1 -1 1];
      sigma = 0.125*MAP_LIMIT^2;
      for i = 1:nPlayers,
        rIndex = mapIndex(i,1):mapIndex(i,2);
        cIndex = mapIndex(i,3):mapIndex(i,4);
        x = mapX(rIndex,cIndex);
        y = mapY(rIndex,cIndex);
        z = mapZ(rIndex,cIndex);
        slope = mapGradient(rIndex,cIndex);
        temp = exp(-((x-muX(i)).^2+(y-muY(i)).^2)./sigma).*...
               rand(size(z)).*((z > 0) & (slope < SLOPE_LIMIT));
        [temp,index] = max(temp(:));
        players(i).position = [x(index) y(index) z(index)];
        players(i).settings = [0 0 100 0];
        players(i).camera = CAMERA_DEFAULT;
      end

    end

    %----------------------------------------------------------------------
    function add_terrain(terrainFile,radius)
    %
    %   Add a terrain pattern to the texture map.
    %
    %----------------------------------------------------------------------

      if any(index(:)),
        terrainFile = fullfile(TEXTURE_PATH,[terrainFile,'.jpg']);
        terrain = reshape(imread(terrainFile),N_PIXELS,3);
        b = imfilter(double(index),fspecial('disk',radius),'replicate');
        mask = (b(:) > 0);
        b = b(mask)*ones(1,3);
        mapC(mask,:) = (1-b).*mapC(mask,:)+b.*double(terrain(mask,:));
      end

    end

  end

  %------------------------------------------------------------------------
  function initialize_game
  %
  %   Initializes the game figure window and uicontrol interface.
  %
  %------------------------------------------------------------------------

    % Initialize variables:

    updateGameFcn = @update_game;
    axesPosition = [1 126 600 410];
    playerData = players(currentPlayer);
    capacity = playerData.capacity;
    settings = playerData.settings;
    cameraProperties = {'CameraPosition','CameraTarget',...
                        'CameraUpVector','CameraViewAngle'};
    cameraData = playerData.camera;
    startMessage = 'Status -';
    for i = 1:nPlayers,
      startMessage = [startMessage '   ' players(i).name ' = ' ...
                      num2str(players(i).capacity,'%6.2f') '%'];
    end
    startTime = datestr(status.suspendedGames(currentGame).lastPlayed);
    startMessage = {startMessage; ['Starting game - ',startTime]};
    windSpeed = [num2str(sqrt(sum(windVector.^2)),'%10.2f'),' mph'];
    windTheta = atan2(windVector(2),windVector(1))-pi/4;
    windData = [cos(windTheta) -sin(windTheta); ...
                sin(windTheta) cos(windTheta)]*...
               [0   0.2 0.1  0.1 -0.1 -0.1 -0.2; ...
                0.4 0.2 0.2 -0.4 -0.4  0.2  0.2];
    blastC = imread(fullfile(TEXTURE_PATH,'fire.jpg'));
    rubbleFile = fullfile(TEXTURE_PATH,'rubble.jpg');
    rubbleC = double(reshape(imread(rubbleFile),N_PIXELS,3));
    isActive = false;
    selection = 'none';
    cameraPoint = [];
    targetPoint = [];
    upVector = [];
    viewAngle = [];
    sightVector = [];
    crossVector = [];
    rotationVector = [];
    currentTheta = [];
    origin = [];

    % Create game figure window:

    hGame = make_figure([1+(SCREEN_SIZE(3:4)-[600 600])./2 600 600],...
                        'CloseRequestFcn',@callback_game,...
                        'Color',edgeColor(2,:),...
                        'Name',['Staker v',BOMB_VERSION],...
                        'Renderer','OpenGL','Resize','on',...
                        'ResizeFcn',@resize_game,'Tag','STAKER_GAME',...
                        'WindowButtonDownFcn',{@mouse_game;'down'},...
                        'WindowButtonMotionFcn',{@mouse_game;'standby'},...
                        'WindowButtonUpFcn',{@mouse_game;'up'});

    % Create axes:

    hMap = make_axes(hGame,axesPosition,cameraProperties,cameraData,...
                     'DataAspectRatio',[1 1 1],...
                     'PlotBoxAspectRatioMode','manual',...
                     'Projection','perspective',...
                     'XLim',MAP_LIMIT.*[-2 2],'YLim',MAP_LIMIT.*[-2 2],...
                     'ZLim',[MIN_HEIGHT 2*MAP_LIMIT]);
    update_limits(cameraData{2}-cameraData{1});

    % Plot terrain:

    hTerrain = plot_surface(hMap,mapX,mapY,mapZ,mapC);

    % Plot terrain edges:

    nAngular = 4*N_MAP-3;
    nRadial = 10;
    theta = linspace(5*pi/4,-3*pi/4,nAngular).';
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -